antispam-bee domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/ruwritingagame/public_html/wp-includes/functions.php on line 6131\u041d\u0430\u0448\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 – \u0432\u044b\u043d\u0435\u0441\u0442\u0438 (\u0443\u0431\u0440\u0430\u0442\u044c) \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b TheGame <\/em>\u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n\n\n\n \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u043e\u043f\u0438\u0441\u0430\u0442\u0435\u043b\u044c<\/em> (text descriptor<\/em>) \u043c\u043e\u0434\u0435\u043b\u0438, XML \u0444\u043e\u0440\u043c\u0430\u0442 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u043c. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u044d\u043a\u0437\u0435\u0448\u043d\u0438\u043a\u0430, \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 \/dt<\/strong>. \u0415\u0449\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c, \u0447\u0438\u0442\u0430\u0442\u044c, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 3D \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438. <\/p>\n\n\n\n \u0423 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c FileLoader <\/strong>\u043a\u043b\u0430\u0441\u0441. \u041d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c XML txt \u0444\u0430\u0439\u043b\u044b. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e XMLParser<\/strong>. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0447\u0430\u0441\u0442\u044c \u0434\u0432\u0438\u0436\u043a\u0430 (engine<\/em>).<\/p>\n\n\n\n 1. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c VS, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c\u00a0C:\\CPP\\a997modeler<\/em>\\p_windows\\p_windows.sln<\/em>.<\/p>\n\n\n\n 2. \u041f\u043e\u0434 xEngine<\/em> \u0434\u043e\u0431\u0430\u0432\u0438\u043c header file XMLParser.h<\/strong><\/p>\n\n\n\n Location: C:\\CPP\\engine<\/em> <\/p>\n\n\n\n \u041a\u043e\u0434:<\/p>\n\n\n <\/p>\n\n\n\n \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u043e\u043d \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 FileLoader<\/em>.<\/p>\n\n\n\n 3. \u041f\u043e\u0434 xEngine<\/em> \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 C++ file XMLParser.cpp<\/strong> <\/p>\n\n\n\n Location: C:\\CPP\\engine<\/em><\/p>\n\n\n\n \u041a\u043e\u0434:<\/p>\n\n\n <\/p>\n\n\n\n \u041a\u043b\u0430\u0441\u0441 XMLParser <\/strong>\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 xml\/txt \u0444\u0430\u0439\u043b, \u0443\u0431\u0435\u0440\u0435\u0442 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u044b, \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0435\u0433\u043e \u0442\u0430\u0433-\u0437\u0430-\u0442\u0430\u0433\u043e\u043c \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e<\/strong> \u0444\u0443\u043d\u043a\u0446\u0438\u044e processTag()<\/em> \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f<\/em> \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0430\u043c XMLParser <\/em>\u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u0447\u0442\u043e <\/strong>\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c\u0438 \u0442\u0430\u0433\u0430\u043c\u0438. \u0411\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0442\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 <\/em>\u043a\u043b\u0430\u0441\u0441 ModelLoader<\/strong>, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 processTag()<\/em>.<\/p>\n\n\n\n \u0422\u0430\u043a\u0436\u0435 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 XMLParser <\/strong>\u0435\u0441\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0442\u0430\u0433\u043e\u0432, \u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n\n\n\n \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 XMLParser<\/em>, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 ModelLoader<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 XML descriptor \u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432 ModelBuilder<\/em>-\u0435. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0442\u044c modeler<\/em><\/strong>-\u0443.<\/p>\n\n\n\n 4. \u041f\u043e\u0434 modeler <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 header file ModelLoader.h<\/strong> <\/p>\n\n\n\n Location: C:\\CPP\\engine\\modeler<\/em><\/p>\n\n\n\n \u041a\u043e\u0434:<\/p>\n\n\n <\/p>\n\n\n\n \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u043e\u043d \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442 XMLParser<\/em> \u043a\u043b\u0430\u0441\u0441.<\/p>\n\n\n\n 5. \u041f\u043e\u0434 modeler <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 C++ file ModelLoader.cpp<\/strong> <\/p>\n\n\n\n Location: C:\\CPP\\engine\\modeler<\/em><\/p>\n\n\n\n \u041a\u043e\u0434:<\/p>\n\n\n <\/p>\n\n\n\n \u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u0434\u043e \u0441\u043b\u0435\u0433\u043a\u0430 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c ModelBuilder1base<\/strong>.<\/p>\n\n\n\n 6. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder1base.h<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n \u0412\u0430\u0436\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f:<\/p>\n\n\n\n 7. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder1base.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n <\/p>\n\n\n\n \u0422\u0435\u043f\u0435\u0440\u044c – \u0441\u0430\u043c\u0430 \u043c\u043e\u0434\u0435\u043b\u044c<\/strong>.<\/p>\n\n\n\n \u0421 \u0442\u0430\u043a\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432 \u043a\u0430\u043a \u0443 \u043d\u0430\u0441, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u0438 \u043e \u0420\u0415\u0410\u041b\u042c\u041d\u041e\u0419 \u043c\u043e\u0434\u0435\u043b\u0438. <\/p>\n\n\n\n \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n\n\n\n <\/p>\n\n\n\n \u041e\u043d\u0430 \u0443\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u0430\u044f, \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u0430\u044f, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u0430\u044f. <\/p>\n\n\n\n \u041d\u0443 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0432\u0435\u0440\u043d\u0443\u043b\u0430\u0441\u044c \u043f\u043e\u0434-\u0440\u0443\u043a\u0443.<\/p>\n\n\n\n \u042f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043b \u0432\u043e\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 \u0432 \u043e\u0434\u043d\u0443 1024×512 PNG \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443:<\/p>\n\n\n\n <\/p>\n\n\n\n
\n\n\n\n\n#pragma once\n#include "FileLoader.h"\n\nclass XMLparser : public FileLoader\n{\npublic:\n\tchar* readFrom;\n\tstd::string currentTag = "";\n\tint tagLength = 0;\n\tstd::string tagName = "";\n\tbool closedTag = false; \/\/ > or \/>\npublic:\n\tXMLparser(std::string filePath) : FileLoader(filePath) { removeComments(this); readFrom = pData; };\n\tstatic int removeComments(XMLparser* pXP);\n\tstatic int processSource(XMLparser* pXP);\n\tint nextTag() { return nextTag(this); }; \/\/returns 0 if no more tags, 1 - tag extractedb\n\tstatic bool nextTag(XMLparser* pXP); \/\/returns 0 if no more tags, 1 - tag extractedb\n\tstatic int nameEndsAt(std::string varName, std::string tag);\n\tvirtual int processTag() { return 1; };\n\tstatic std::string buildFullPath(XMLparser* pXP, std::string filePath);\n\n\tstatic bool varExists(std::string varName, std::string tag);\n\tstatic std::string getStringValue(std::string varName, std::string tag);\n\tstatic int setCharsValue(char* pChars, int charsLength, std::string varName, std::string tag);\n\tstatic int setIntValue(int* pInt, std::string varName, std::string tag);\n\tstatic int setFloatValue(float* pFloat, std::string varName, std::string tag);\n\tstatic int setIntArray(int* pInts, int arrayLength, std::string varName, std::string tag);\n\tstatic int setFloatArray(float* pFloats, int arrayLength, std::string varName, std::string tag);\n\tstatic int setUintColorValue(unsigned int* pInt, std::string varName, std::string tag);\n\tstatic int setIntBoolValue(int* pInt, std::string varName, std::string tag);\n};\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#include "XMLparser.h"\n#include "platform.h"\n#include "utils.h"\n#include "MyColor.h"\n#include <vector>\n\nextern std::string filesRoot;\n\nint XMLparser::removeComments(XMLparser* pXP) {\n\t\/\/find all occurances of "\/*"\n\tstd::vector<char*> commentsStarts;\n\t\/\/ \/* comments *\/\n\tchar* scanFrom = pXP->pData;\n\twhile (1) {\n\t\tchar* commentStarts = strstr(scanFrom, "\/*");\n\t\tif (commentStarts == NULL)\n\t\t\tbreak;\n\t\tcommentsStarts.push_back(commentStarts);\n\t\tscanFrom = commentStarts + 2;\n\t}\n\t\/\/here we have a list of \/* comments *\/\n\twhile(commentsStarts.size() > 0){\n\t\t\/\/get last comment\n\t\tchar* commentStarts = commentsStarts.back();\n\t\tcommentsStarts.pop_back();\n\t\tchar* commentEnds = strstr(commentStarts, "*\/");\n\t\tint commentLength = (int)(commentEnds - commentStarts) + 2;\n\t\t\/\/shift text left\n\t\tmyStrcpy_s(commentStarts, pXP->dataSize - (int)(commentStarts - pXP->pData), commentStarts + commentLength);\n\t\tpXP->dataSize -= commentLength;\n\/\/mylog("======\\n%s----------\\n", pXP->pData);\n\t}\n\t\/\/ \/\/line comments\n\tscanFrom = pXP->pData;\n\twhile (1) {\n\t\tchar* commentStarts = strstr(scanFrom, "\/\/");\n\t\tif (commentStarts == NULL)\n\t\t\tbreak;\n\t\tchar* commentEnds = strstr(commentStarts, "\\n");\n\t\tint commentLength = (int)(commentEnds - commentStarts) + 1;\n\t\t\/\/shift text left\n\t\tmyStrcpy_s(commentStarts, pXP->dataSize - (int)(commentStarts - pXP->pData), commentStarts + commentLength);\n\t\tpXP->dataSize -= commentLength;\n\t\tscanFrom = commentStarts;\n\/\/mylog("======\\n%s----------\\n", pXP->pData);\n\t}\n\t\/\/ <!-- comments -->\n\tscanFrom = pXP->pData;\n\twhile (1) {\n\t\tchar* commentStarts = strstr(scanFrom, "<!--");\n\t\tif (commentStarts == NULL)\n\t\t\tbreak;\n\t\tcommentsStarts.push_back(commentStarts);\n\t\tscanFrom = commentStarts + 4;\n\t}\n\t\/\/here we have a list of <!-- comments -->\n\twhile (commentsStarts.size() > 0) {\n\t\t\/\/get last comment\n\t\tchar* commentStarts = commentsStarts.back();\n\t\tcommentsStarts.pop_back();\n\t\tchar* commentEnds = strstr(commentStarts, "-->");\n\t\tint commentLength = (int)(commentEnds - commentStarts) + 3;\n\t\t\/\/shift text left\n\t\tmyStrcpy_s(commentStarts, pXP->dataSize - (int)(commentStarts - pXP->pData), commentStarts + commentLength);\n\t\tpXP->dataSize -= commentLength;\n\/\/mylog("======\\n%s----------\\n", pXP->pData);\n\t}\n\treturn 1;\n}\nbool XMLparser::nextTag(XMLparser* pXP) {\n\t\/\/returns 0 if no more tags, 1 - tag extracted\n\tchar* tagStarts = strstr(pXP->readFrom, "<");\n\tif (tagStarts == NULL)\n\t\treturn false;\n\tpXP->readFrom++;\n\tchar* tagEnds = strstr(pXP->readFrom, ">");\n\tif (tagEnds == NULL)\n\t\treturn false;\n\tpXP->readFrom = tagEnds + 1;\n\tpXP->tagLength = (int)(tagEnds - tagStarts) + 1;\n\tpXP->currentTag.assign(tagStarts, pXP->tagLength);\n\treturn true;\n} \nint XMLparser::nameEndsAt(std::string varName, std::string tag) {\n\tint scanFrom = 0;\n\tint nameLength = varName.length();\n\tstd::string optsBefore = "< ";\n\tstd::string optsAfter = " =\/>\\n";\n\twhile (1) {\n\t\tint varStartsAt = tag.find(varName, scanFrom);\n\t\tif (varStartsAt == std::string::npos)\n\t\t\treturn -1;\n\t\tscanFrom = varStartsAt + nameLength;\n\t\tchar charBefore = tag.at(varStartsAt - 1);\n\t\tif (optsBefore.find(charBefore) == std::string::npos)\n\t\t\tcontinue;\n\t\tchar charAfter = tag.at(scanFrom);\n\t\tif (optsAfter.find(charAfter) == std::string::npos)\n\t\t\tcontinue;\n\t\treturn scanFrom;\n\t}\n}\nint XMLparser::processSource(XMLparser* pXP) {\n\twhile (pXP->nextTag()) {\n\t\t\/\/extract tagName\n\t\tint nameStart = pXP->currentTag.find_first_not_of(" <");\n\t\tint nameEnd = pXP->currentTag.find_first_of(" =\/>\\n", nameStart+1);\n\t\tpXP->tagName = pXP->currentTag.substr(nameStart, (nameEnd - nameStart));\n\t\t\/\/open\/closed tag\n\t\tchar lastChar = pXP->currentTag.at(pXP->tagLength - 2);\n\t\tpXP->closedTag = (lastChar == '\/');\n\/\/mylog("[%s] [%s] closed=%d nameStart=%d nameEnd=%d\\n", pXP->currentTag.c_str(), pXP->tagName.c_str(), pXP->closedTag, nameStart, nameEnd);\n\t\tpXP->processTag();\n\t}\n\treturn 1;\n}\nstd::string XMLparser::buildFullPath(XMLparser* pXP, std::string filePath) {\n\tif (filePath.at(0) != '\/')\n\t\tfilePath = pXP->inAppFolder + filePath;\n\treturn (filesRoot + filePath);\n}\n\nstd::string XMLparser::getStringValue(std::string varName, std::string tag) {\n\t\/\/returns std::string\n\tint valueStartsAt = nameEndsAt(varName, tag);\n\tif (valueStartsAt < 0)\n\t\treturn ""; \/\/var not found\n\tvalueStartsAt = tag.find_first_not_of(" ", valueStartsAt);\n\tchar c = tag.at(valueStartsAt);\n\tif (c != '=')\n\t\treturn ""; \/\/var exists, but value not set\n\tvalueStartsAt = tag.find_first_not_of(" ", valueStartsAt + 1);\n\tc = tag.at(valueStartsAt);\n\tstd::string optsQuote = "\\"'";\n\tint valueEndsAt = 0;\n\tif (optsQuote.find(c) != std::string::npos) {\n\t\t\/\/the value is in quotes\n\t\tvalueStartsAt++;\n\t\tvalueEndsAt = tag.find(c, valueStartsAt);\n\t}\n\telse { \/\/value not quoted\n\t\tvalueEndsAt = tag.find_first_of(" \/>\\n", valueStartsAt);\n\t}\n\treturn tag.substr(valueStartsAt, valueEndsAt - valueStartsAt);\n}\n\nbool XMLparser::varExists(std::string varName, std::string tag) {\n\tint valueStartsAt = nameEndsAt(varName, tag);\n\tif (valueStartsAt < 0)\n\t\treturn false; \/\/var not found\n\treturn true;\n}\nint XMLparser::setCharsValue(char* pChars, int charsLength, std::string varName, std::string tag) {\n\tif (!varExists(varName, tag))\n\t\treturn 0; \/\/var not found\n\tstd::string val = getStringValue(varName, tag);\n\tmyStrcpy_s(pChars, charsLength, (char*)val.c_str());\n\treturn 1;\n}\nint XMLparser::setIntValue(int* pInt, std::string varName, std::string tag) {\n\tif (!varExists(varName, tag))\n\t\treturn 0; \/\/var not found\n\tstd::string val = getStringValue(varName, tag);\n\t*pInt = stoi(val);\n\treturn 1;\n}\nint XMLparser::setFloatValue(float* pFloat, std::string varName, std::string tag) {\n\tif (!varExists(varName, tag))\n\t\treturn 0; \/\/var not found\n\tstd::string val = getStringValue(varName, tag);\n\t*pFloat = stof(val);\n\treturn 1;\n}\nint XMLparser::setFloatArray(float* pFloats, int arrayLength, std::string varName, std::string tag) {\n\tif (!varExists(varName, tag))\n\t\treturn 0; \/\/var not found\n\tstd::string valuesString = getStringValue(varName, tag);\n\tstd::vector<std::string> valuesVector = splitString(valuesString, ",");\n\tint valsN = valuesVector.size();\n\tif (valsN != arrayLength) {\n\t\tmylog("ERROR in XMLparser::getFloatArray, %s, %s\\n", varName.c_str(), tag.c_str());\n\t\treturn -1;\n\t}\n\tfor (int i = 0; i < valsN; i++) {\n\t\tif (valuesVector.at(i).compare("x") != 0)\n\t\t\tpFloats[i] = stof(valuesVector.at(i));\n\t}\n\treturn 1;\n}int XMLparser::setIntArray(int* pInts, int arrayLength, std::string varName, std::string tag) {\n\tif (!varExists(varName, tag))\n\t\treturn 0; \/\/var not found\n\tstd::string valuesString = getStringValue(varName, tag);\n\tstd::vector<std::string> valuesVector = splitString(valuesString, ",");\n\tint valsN = valuesVector.size();\n\tif (valsN != arrayLength) {\n\t\tmylog("ERROR in XMLparser::getIntArray, %s, %s\\n", varName.c_str(), tag.c_str());\n\t\treturn -1;\n\t}\n\tfor (int i = 0; i < valsN; i++) {\n\t\tif(valuesVector.at(i).compare("x") != 0)\n\t\t\tpInts[i] = stoi(valuesVector.at(i));\n\t}\n\treturn 1;\n}\nint XMLparser::setUintColorValue(unsigned int* pInt, std::string varName, std::string tag) {\n\tif (!varExists(varName, tag))\n\t\treturn 0; \/\/var not found\n\tMyColor clr;\n\tstd::string val = getStringValue(varName, tag);\n\tif (val.at(0) == '#') {\n\t\t\/\/the value is in HTML HEX format (like #ff0000)\n\t\tint r = std::stoi(val.substr(1, 2), nullptr, 16);\n\t\tint g = std::stoi(val.substr(3, 2), nullptr, 16);\n\t\tint b = std::stoi(val.substr(5, 2), nullptr, 16);\n\t\tint a = 255;\n\t\tif (val.size() > 7)\n\t\t\ta = std::stoi(val.substr(7, 2), nullptr, 16);\n\t\tclr.setRGBA(r, g, b, a);\n\t}\n\telse if (val.find(",") > 0) {\n\t\t\/\/the value is an array of ints (?)\n\t\tstd::vector<std::string> valuesVector = splitString(val, ",");\n\t\tint r = std::stoi(valuesVector[0]);\n\t\tint g = std::stoi(valuesVector[1]);\n\t\tint b = std::stoi(valuesVector[2]);\n\t\tint a = 255;\n\t\tif (valuesVector.size() > 3)\n\t\t\ta = std::stoi(valuesVector[3]);\n\t\tclr.setRGBA(r, g, b, a);\n\t}\n\telse {\n\t\tmylog("ERROR in XMLparser::setUintColorValue: unhandled Color format %s\\n",tag.c_str());\n\t\treturn -1;\n\t}\n\t*pInt = clr.getUint32();\n\treturn 1;\n}\nint XMLparser::setIntBoolValue(int* pInt, std::string varName, std::string tag) {\n\tif (!varExists(varName, tag))\n\t\treturn 0; \/\/var not found\n\tstd::string val = getStringValue(varName, tag);\n\tif (val.compare("") == 0) *pInt = 1;\n\telse if (val.compare("1") == 0) *pInt = 1;\n\telse if (val.compare("0") == 0) *pInt = 0;\n\telse if (val.compare("yes") == 0) *pInt = 1;\n\telse if (val.compare("no") == 0) *pInt = 0;\n\telse if (val.compare("true") == 0) *pInt = 1;\n\telse if (val.compare("false") == 0) *pInt = 0;\n\telse {\n\t\tmylog("ERROR in XMLparser::setIntBoolValue, %s=%s in %s\\n",varName.c_str(),val.c_str(),tag.c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#pragma once\n#include "XMLparser.h"\n#include "ModelBuilder.h"\n\nclass ModelLoader : public XMLparser\n{\npublic:\n\tModelBuilder* pModelBuilder = NULL;\n\tbool ownModelBuilder = false;\n\tstd::vector<GameSubj*>* pSubjsVector = NULL;\npublic:\n\tModelLoader(std::vector<GameSubj*>* pSubjsVector0, int subjN, ModelBuilder* pMB, std::string filePath) : XMLparser(filePath) {\n\t\tpSubjsVector = pSubjsVector0;\n\t\tif (pMB != NULL) {\n\t\t\townModelBuilder = false;\n\t\t\tpModelBuilder = pMB;\n\t\t}\n\t\telse {\n\t\t\townModelBuilder = true;\n\t\t\tpModelBuilder = new ModelBuilder();\n\t\t}\n\t\tpModelBuilder->useSubjN(subjN);\n\t};\n\tvirtual ~ModelLoader() {\n\t\tif (!ownModelBuilder)\n\t\t\treturn;\n\t\tpModelBuilder->buildDrawJobs(*pSubjsVector);\n\t\tdelete pModelBuilder;\n\t};\n\tstatic int fillProps_vs(VirtualShape* pVS, std::string tagStr); \/\/virtual shape\n\tstatic int processTag_a(ModelLoader* pML); \/\/apply\n\tstatic int setValueFromIntHashMap(int* pInt, std::map<std::string, int> intHashMap, std::string varName, std::string tagStr);\n\tstatic int setTexture(ModelLoader* pML, int* pInt, std::string txName);\n\tstatic int setMaterialTextures(ModelLoader* pML, Material* pMT);\n\tstatic int fillProps_mt(Material* pMT, std::string tagStr, ModelLoader* pML); \/\/Material\n\tint processTag() { return processTag(this); };\n\tstatic int processTag(ModelLoader* pML);\n\tstatic int loadModel(std::vector<GameSubj*>* pSubjsVector0, std::string sourceFile, std::string subjClass);\n};\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#include "ModelLoader.h"\n#include "platform.h"\n#include "TheGame.h"\n#include "DrawJob.h"\n#include "Texture.h"\n#include "utils.h"\n\nextern TheGame theGame;\n\nint ModelLoader::loadModel(std::vector<GameSubj*>* pSubjsVector0, std::string sourceFile, std::string subjClass) {\n\t\/\/returns element's (Subj) number or -1\n\tint subjN = pSubjsVector0->size();\n\tGameSubj* pGS = theGame.newGameSubj(subjClass);\n\tpSubjsVector0->push_back(pGS);\n\t\/\/pGS->djStartN = DrawJob::drawJobs.size();\n\tModelLoader* pML = new ModelLoader(pSubjsVector0, subjN, NULL, sourceFile);\n\tprocessSource(pML);\n\tdelete pML;\n\t\/\/pGS->djTotalN = DrawJob::drawJobs.size() - pGS->djStartN;\n\treturn subjN;\n}\nint ModelLoader::processTag_a(ModelLoader* pML) {\n\t\/\/apply\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tstd::string tagStr = pML->currentTag;\n\tpMB->lockGroup(pMB);\n\n\tstd::vector<std::string> applyTosVector = splitString(pML->getStringValue("a", tagStr), ",");\n\tMaterial* pMT = pMB->materialsList.at(pMB->usingMaterialN);\n\tint texN = pMT->uTex1mask;\n\tif (texN < 0)\n\t\ttexN = pMT->uTex0;\n\tfloat xywh[4] = { 0,0,1,1 };\n\tsetFloatArray(xywh, 4, "xywh", tagStr);\n\tstd::string flipStr = getStringValue("flip", tagStr);\n\tTexCoords tc;\n\ttc.set(texN, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\n\tsetFloatArray(xywh, 4, "xywh2nm", tagStr);\n\tflipStr = getStringValue("flip2nm", tagStr);\n\tTexCoords tc2nm;\n\ttc2nm.set(pMT->uTex2nm, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\n\tfor (int aN = 0; aN < (int)applyTosVector.size(); aN++) {\n\t\tpMB->buildFace(pMB, applyTosVector.at(aN), pMB->pCurrentVShape, &tc, &tc2nm);\n\t}\n\t\/\/mylog("vertsN=%d\\n",pMB->vertices.size());\n\n\tpMB->releaseGroup(pMB);\n\treturn 1;\n}\nint ModelLoader::setValueFromIntHashMap(int* pInt, std::map<std::string, int> intHashMap, std::string varName, std::string tagStr) {\n\tif (!varExists(varName, tagStr))\n\t\treturn 0;\n\tstd::string str0 = getStringValue(varName, tagStr);\n\tif (intHashMap.find(str0) == intHashMap.end()) {\n\t\tmylog("ERROR in ModelLoader::setValueFromIntMap, %s not found, %s\\n", varName.c_str(), tagStr.c_str());\n\t\treturn -1;\n\t}\n\t*pInt = intHashMap[getStringValue(varName, tagStr)];\n\treturn 1;\n}\nint ModelLoader::setTexture(ModelLoader* pML, int* pInt, std::string txName) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tstd::string varName = txName + "_use";\n\tif (setValueFromIntHashMap(pInt, pMB->texturesHashMap, varName, pML->currentTag) == 0) {\n\t\t\/\/the texture is not in hash table\n\t\tvarName = txName + "_src";\n\t\tif (varExists(varName, pML->currentTag)) {\n\t\t\tstd::string txFile = getStringValue(varName, pML->currentTag);\n\t\t\tvarName = txName + "_ckey";\n\t\t\tunsigned int intCkey = 0;\n\t\t\tsetUintColorValue(&intCkey, varName, pML->currentTag);\n\t\t\t*pInt = Texture::loadTexture(buildFullPath(pML, txFile), intCkey);\n\t\t}\n\t}\n\treturn 1;\n}\nint ModelLoader::setMaterialTextures(ModelLoader* pML, Material* pMT) {\n\tsetTexture(pML, &pMT->uTex0, "uTex0");\n\tsetTexture(pML, &pMT->uTex1mask, "uTex1mask");\n\tsetTexture(pML, &pMT->uTex2nm, "uTex2nm");\n\tsetTexture(pML, &pMT->uTex3, "uTex3");\n\treturn 1;\n}\nint ModelLoader::fillProps_mt(Material* pMT, std::string tagStr, ModelLoader* pML) {\n\tsetCharsValue(pMT->shaderType, 20, "mt_type", tagStr);\n\tsetMaterialTextures(pML, pMT);\n\t\/\/color\n\tif (varExists("uColor", tagStr)) {\n\t\tunsigned int uintColor = 0;\n\t\tsetUintColorValue(&uintColor, "uColor", tagStr);\n\t\tpMT->uColor.setUint32(uintColor);\n\t}\n\t\/\/mylog("mt.uTex0=%d, mt.uTex1mask=%d\\n", mt.uTex0, mt.uTex1mask);\n\tif (varExists("primitiveType", tagStr)) {\n\t\tstd::string str0 = getStringValue("primitiveType", tagStr);\n\t\tif (str0.compare("GL_POINTS") == 0) pMT->primitiveType = GL_POINTS;\n\t\telse if (str0.compare("GL_LINES") == 0) pMT->primitiveType = GL_LINES;\n\t\telse if (str0.compare("GL_LINE_STRIP") == 0) pMT->primitiveType = GL_LINE_STRIP;\n\t\telse if (str0.compare("GL_LINE_LOOP") == 0) pMT->primitiveType = GL_LINE_LOOP;\n\t\telse if (str0.compare("GL_TRIANGLE_STRIP") == 0) pMT->primitiveType = GL_TRIANGLE_STRIP;\n\t\telse if (str0.compare("GL_TRIANGLE_FAN") == 0) pMT->primitiveType = GL_TRIANGLE_FAN;\n\t\telse pMT->primitiveType = GL_TRIANGLES;\n\t}\n\tsetIntValue(&pMT->uTex1alphaChannelN, "uTex1alphaChannelN", tagStr);\n\tsetIntValue(&pMT->uTex0translateChannelN, "uTex0translateChannelN", tagStr);\n\tsetIntBoolValue(&pMT->uAlphaBlending, "uAlphaBlending", tagStr);\n\tsetFloatValue(&pMT->uAlphaFactor, "uAlphaFactor", tagStr);\n\tsetFloatValue(&pMT->uAmbient, "uAmbient", tagStr);\n\tsetFloatValue(&pMT->uSpecularIntencity, "uSpecularIntencity", tagStr);\n\tsetFloatValue(&pMT->uSpecularMinDot, "uSpecularMinDot", tagStr);\n\tsetFloatValue(&pMT->uSpecularPowerOf, "uSpecularPowerOf", tagStr);\n\n\tpML->pModelBuilder->useMaterial(pMT);\n\treturn 1;\n}\nint ModelLoader::processTag(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tif (pML->tagName.compare("texture_as") == 0) {\n\t\t\/\/saves texture N in texturesMap under given name\n\t\tstd::string keyName = getStringValue("texture_as", pML->currentTag);\n\t\tif (pMB->texturesHashMap.find(keyName) != pMB->texturesHashMap.end())\n\t\t\treturn pMB->texturesHashMap[keyName];\n\t\telse { \/\/add new\n\t\t\tstd::string txFile = getStringValue("src", pML->currentTag);\n\t\t\tunsigned int intCkey = 0;\n\t\t\tsetUintColorValue(&intCkey, "ckey", pML->currentTag);\n\t\t\tint txN = Texture::loadTexture(buildFullPath(pML, txFile), intCkey);\n\t\t\tpMB->texturesHashMap[keyName] = txN;\n\t\t\t\/\/mylog("%s=%d\\n", keyName.c_str(), pMB->texturesMap[keyName]);\n\t\t\treturn txN;\n\t\t}\n\t}\n\tif (pML->tagName.find("mt_") == 0) {\n\t\t\/\/sets current material\n\t\tModelBuilder* pMB = pML->pModelBuilder;\n\t\tif (!pML->closedTag) {\n\t\t\t\/\/save previous material in stack\n\t\t\tif (pMB->usingMaterialN >= 0)\n\t\t\t\tpMB->materialsStack.push_back(pMB->usingMaterialN);\n\t\t}\n\t\tMaterial mt;\n\t\treturn fillProps_mt(&mt, pML->currentTag, pML);\n\t}\n\tif (pML->tagName.find("\/mt_") == 0) {\n\t\t\/\/restore previous material\n\t\tif (pMB->materialsStack.size() > 0) {\n\t\t\tpMB->usingMaterialN = pMB->materialsStack.back();\n\t\t\tpMB->materialsStack.pop_back();\n\t\t}\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("vs") == 0) {\n\t\t\/\/sets virtual shape\n\t\tModelBuilder* pMB = pML->pModelBuilder;\n\t\tif (pML->closedTag) {\n\t\t\tif (pMB->pCurrentVShape != NULL)\n\t\t\t\tdelete pMB->pCurrentVShape;\n\t\t}\n\t\telse { \/\/open tag\n\t\t\t\/\/save previous vshape in stack\n\t\t\tif (pMB->pCurrentVShape != NULL)\n\t\t\t\tpMB->vShapesStack.push_back(pMB->pCurrentVShape);\n\t\t}\n\t\tpMB->pCurrentVShape = new VirtualShape();\n\t\tfillProps_vs(pMB->pCurrentVShape, pML->currentTag);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/vs") == 0) {\n\t\t\/\/restore previous virtual shape\n\t\tif (pMB->vShapesStack.size() > 0) {\n\t\t\tif (pMB->pCurrentVShape != NULL)\n\t\t\t\tdelete(pMB->pCurrentVShape);\n\t\t\tpMB->pCurrentVShape = pMB->vShapesStack.back();\n\t\t\tpMB->vShapesStack.pop_back();\n\t\t}\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("group") == 0) {\n\t\tstd::string notAllowed[] = { "pxyz","axyz","align","headTo" };\n\t\tint notAllowedLn = sizeof(notAllowed) \/ sizeof(notAllowed[0]);\n\t\tfor (int i = 0; i < notAllowedLn; i++)\n\t\t\tif (varExists(notAllowed[i], pML->currentTag)) {\n\t\t\t\tmylog("ERROR in ModelLoader::processTag: use %s in <\/group>: %s\\n", notAllowed[i].c_str(), pML->currentTag.c_str());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\tpMB->lockGroup(pMB);\n\t\treturn 1;\n\t}\n\t\/\/mylog("%s, %s \/group?=%d\\n",pML->currentTag.c_str(), pML->tagName.c_str(), (pML->tagName.compare("\/group") == 0));\n\tif (pML->tagName.compare("\/group") == 0) {\n\t\tpMB->releaseGroup(pMB);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("a") == 0)\n\t\treturn processTag_a(pML); \/\/apply \n\n\tmylog("ERROR in ModelLoader::processTag, unhandled tag %s, file %s\\n", pML->currentTag.c_str(), pML->fullPath.c_str());\n\treturn -1;\n}\nint ModelLoader::fillProps_vs(VirtualShape* pVS, std::string tagStr) {\n\t\/\/sets virtual shape\n\tsetCharsValue(pVS->shapeType, 20, "vs", tagStr);\n\tsetFloatArray(pVS->whl, 3, "whl", tagStr);\n\t\/\/extensions\n\tfloat ext;\n\tif (varExists("ext", tagStr)) {\n\t\tsetFloatValue(&ext, "ext", tagStr);\n\t\tpVS->setExt(ext);\n\t}\n\tif (varExists("extX", tagStr)) {\n\t\tsetFloatValue(&ext, "extX", tagStr);\n\t\tpVS->setExtX(ext);\n\t}\n\tif (varExists("extY", tagStr)) {\n\t\tsetFloatValue(&ext, "extY", tagStr);\n\t\tpVS->setExtY(ext);\n\t}\n\tif (varExists("extZ", tagStr)) {\n\t\tsetFloatValue(&ext, "extZ", tagStr);\n\t\tpVS->setExtZ(ext);\n\t}\n\tsetFloatValue(&pVS->extU, "extU", tagStr);\n\tsetFloatValue(&pVS->extD, "extD", tagStr);\n\tsetFloatValue(&pVS->extL, "extL", tagStr);\n\tsetFloatValue(&pVS->extR, "extR", tagStr);\n\tsetFloatValue(&pVS->extF, "extF", tagStr);\n\tsetFloatValue(&pVS->extB, "extB", tagStr);\n\t\/\/sections\n\tsetIntValue(&pVS->sectionsR, "sectR", tagStr);\n\tsetIntValue(&pVS->sections[0], "sectX", tagStr);\n\tsetIntValue(&pVS->sections[1], "sectY", tagStr);\n\tsetIntValue(&pVS->sections[2], "sectZ", tagStr);\n\n\t\/\/mylog("pVS->shapeType=%s whl=%fx%fx%f\\n", pVS->shapeType, pVS->whl[0], pVS->whl[1], pVS->whl[2]);\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#pragma once\n#include <string>\n#include <vector>\n#include "Vertex01.h"\n#include "Triangle01.h"\n#include "VirtualShape.h"\n#include "Group01.h"\n#include "Material.h"\n#include "GameSubj.h"\n#include <map>\n\nclass ModelBuilder1base\n{\npublic:\n\tstd::vector<Vertex01*> vertices;\n\tstd::vector<Triangle01*> triangles;\n\tstd::vector<int> subjNumbersList;\n\tint usingSubjN = -1;\n\n\tstd::vector<Group01*> groupsStack;\n\tGroup01* pCurrentGroup = NULL;\n\n\tstd::vector<VirtualShape*> vShapesStack;\n\tVirtualShape* pCurrentVShape = NULL;\n\n\tstd::vector<Material*> materialsList;\n\tint usingMaterialN = -1;\n\tstd::vector<int> materialsStack;\n\n\tstd::map<std::string, int> texturesHashMap;\npublic:\n\tvirtual ~ModelBuilder1base();\n\tint useSubjN(int subjN) { return useSubjN(this, subjN); };\n\tstatic int useSubjN(ModelBuilder1base* pMB, int subjN);\n\tint useMaterial(Material* pMT) { return useMaterial(this, pMT); };\n\tstatic int useMaterial(ModelBuilder1base* pMB, Material* pMT);\n\tstatic void lockGroup(ModelBuilder1base* pMB);\n\tstatic void releaseGroup(ModelBuilder1base* pMB);\n\tstatic int addVertex(ModelBuilder1base* pMB, float kx, float ky, float kz, float nx, float ny, float nz);\n\tstatic int add2triangles(ModelBuilder1base* pMB, int nNW, int nNE, int nSW, int nSE, int n);\n\tstatic int addTriangle(ModelBuilder1base* pMB, int n0, int n1, int n2);\n\tint buildDrawJobs(std::vector<GameSubj*> gameSubjs) { return buildDrawJobs(this, gameSubjs); };\n\tstatic int buildDrawJobs(ModelBuilder1base* pMB, std::vector<GameSubj*> gameSubjs);\n\tstatic int rearrangeArraysForDrawJob(ModelBuilder1base* pMB, std::vector<Vertex01*> allVertices, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles);\n\tstatic int buildSingleDrawJob(Material* pMT, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles);\n\tstatic int moveGroupDg(ModelBuilder1base* pMB, float aX, float aY, float aZ, float kX, float kY, float kZ);\n};\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#include "ModelBuilder1base.h"\n#include "platform.h"\n#include "utils.h"\n#include "DrawJob.h"\n#include "Shader.h"\n\nextern float degrees2radians;\n\nModelBuilder1base::~ModelBuilder1base() {\n\t\/\/clear all vectors\n\tint itemsN = vertices.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete vertices.at(i);\n\tvertices.clear();\n\n\titemsN = triangles.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete triangles.at(i);\n\ttriangles.clear();\n\n\titemsN = vShapesStack.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete vShapesStack.at(i);\n\tvShapesStack.clear();\n\n\titemsN = groupsStack.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete groupsStack.at(i);\n\tgroupsStack.clear();\n\n\titemsN = materialsList.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete materialsList.at(i);\n\tmaterialsList.clear();\n\n\tsubjNumbersList.clear();\n}\nint ModelBuilder1base::useSubjN(ModelBuilder1base* pMB, int subjN) {\n\tpMB->usingSubjN = subjN;\n\tint itemsN = pMB->subjNumbersList.size();\n\tbool newN = true;\n\tif (itemsN > 0)\n\t\tfor (int i = 0; i < itemsN; i++)\n\t\t\tif (pMB->subjNumbersList.at(i) == subjN) {\n\t\t\t\tnewN = false;\n\t\t\t\tbreak;\n\t\t\t}\n\tif (newN)\n\t\tpMB->subjNumbersList.push_back(subjN);\n\treturn subjN;\n}\nint ModelBuilder1base::useMaterial(ModelBuilder1base* pMB, Material* pMT) {\n\tint itemsN = pMB->materialsList.size();\n\tif (itemsN > 0)\n\t\tfor (int i = 0; i < itemsN; i++)\n\t\t\tif (memcmp(pMB->materialsList.at(i), pMT, sizeof(Material)) == 0) {\n\t\t\t\tpMB->usingMaterialN = i;\n\t\t\t\treturn i;\n\t\t\t}\n\t\/\/if here - add new material to the list\n\tpMB->usingMaterialN = itemsN;\n\t\/\/create a copy of new Material and add to the list\n\tMaterial* pMTnew = new Material(*pMT);\n\tpMB->materialsList.push_back(pMTnew);\n\treturn itemsN;\n}\nint ModelBuilder1base::add2triangles(ModelBuilder1base* pMB, int nNW, int nNE, int nSW, int nSE, int n) {\n\t\/\/indexes: NorthWest, NorthEast, SouthWest,SouthEast\n\tif (n % 2 == 0) { \/\/even number\n\t\taddTriangle(pMB, nNW, nSW, nNE);\n\t\taddTriangle(pMB, nNE, nSW, nSE);\n\t}\n\telse { \/\/odd number\n\t\taddTriangle(pMB, nNW, nSE, nNE);\n\t\taddTriangle(pMB, nNW, nSW, nSE);\n\t}\n\treturn pMB->triangles.size() - 1;\n}\nint ModelBuilder1base::addTriangle(ModelBuilder1base* pMB, int i0, int i1, int i2) {\n\tTriangle01* pTR = new Triangle01();\n\tpMB->triangles.push_back(pTR);\n\tpTR->idx[0] = i0;\n\tpTR->idx[1] = i1;\n\tpTR->idx[2] = i2;\n\tpTR->subjN = pMB->usingSubjN;\n\tpTR->materialN = pMB->usingMaterialN;\n\treturn pMB->triangles.size() - 1;\n}\nint ModelBuilder1base::addVertex(ModelBuilder1base* pMB, float kx, float ky, float kz, float nx, float ny, float nz) {\n\tVertex01* pVX = new Vertex01();\n\tpMB->vertices.push_back(pVX);\n\tpVX->aPos[0] = kx;\n\tpVX->aPos[1] = ky;\n\tpVX->aPos[2] = kz;\n\t\/\/normal\n\tpVX->aNormal[0] = nx;\n\tpVX->aNormal[1] = ny;\n\tpVX->aNormal[2] = nz;\n\tpVX->subjN = pMB->usingSubjN;\n\tpVX->materialN = pMB->usingMaterialN;\n\treturn pMB->vertices.size() - 1;\n}\nint ModelBuilder1base::buildDrawJobs(ModelBuilder1base* pMB, std::vector<GameSubj*> gameSubjs) {\n\tint totalSubjsN = pMB->subjNumbersList.size();\n\tif (totalSubjsN < 1) {\n\t\tpMB->subjNumbersList.push_back(-1);\n\t\ttotalSubjsN = 1;\n\t}\n\tint totalMaterialsN = pMB->materialsList.size();\n\tif (totalSubjsN < 2 && totalMaterialsN < 2) {\n\t\t\/\/simple single DrawJob\n\t\tMaterial* pMT = pMB->materialsList.at(0);\n\t\tGameSubj* pGS = NULL;\n\t\tint gsN = pMB->subjNumbersList.at(0);\n\t\tif (gsN >= 0)\n\t\t\tpGS = gameSubjs.at(gsN);\n\t\tif (pGS != NULL)\n\t\t\tpGS->djStartN = DrawJob::drawJobs.size();\n\t\tbuildSingleDrawJob(pMT, pMB->vertices, pMB->triangles);\n\t\tif (pGS != NULL)\n\t\t\tpGS->djTotalN = DrawJob::drawJobs.size() - pGS->djStartN;\n\t\treturn 1;\n\t}\n\tint totalVertsN = pMB->vertices.size();\n\tint totalTrianglesN = pMB->triangles.size();\n\t\/\/clear flags\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pVX = pMB->vertices.at(vN);\n\t\tpVX->flag = 0;\n\t}\n\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\tTriangle01* pTR = pMB->triangles.at(tN);\n\t\tpTR->flag = 0;\n\t}\n\tint addedDJs = 0;\n\tfor (int sN = 0; sN < totalSubjsN; sN++) {\n\t\tGameSubj* pGS = NULL;\n\t\tint gsN = pMB->subjNumbersList.at(sN);\n\t\tif (gsN >= 0)\n\t\t\tpGS = gameSubjs.at(gsN);\n\t\tif (pGS != NULL)\n\t\t\tpGS->djStartN = DrawJob::drawJobs.size();\n\t\tfor (int mtN = 0; mtN < totalMaterialsN; mtN++) {\n\t\t\tMaterial* pMT = pMB->materialsList.at(mtN);\n\t\t\tstd::vector<Vertex01*> useVertices;\n\t\t\tstd::vector<Triangle01*> useTriangles;\n\t\t\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\t\t\tVertex01* pVX = pMB->vertices.at(vN);\n\t\t\t\tif (pVX->flag != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pVX->subjN != gsN)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pVX->materialN != mtN)\n\t\t\t\t\tcontinue;\n\t\t\t\t\/\/if here - make a copy\n\t\t\t\tVertex01* pVX2 = new Vertex01(*pVX);\n\t\t\t\tuseVertices.push_back(pVX2);\n\t\t\t\tpVX2->altN = vN;\n\t\t\t\tpVX->flag = 1;\n\t\t\t\tif (pVX->endOfSequence > 0) {\n\t\t\t\t\trearrangeArraysForDrawJob(pMB, pMB->vertices, useVertices, useTriangles);\n\t\t\t\t\tbuildSingleDrawJob(pMT, useVertices, useTriangles);\n\t\t\t\t\taddedDJs++;\n\t\t\t\t\t\/\/clear and proceed to next sequence\n\t\t\t\t\tint useVerticesN = useVertices.size();\n\t\t\t\t\tfor (int i = 0; i < useVerticesN; i++)\n\t\t\t\t\t\tdelete useVertices.at(i);\n\t\t\t\t\tuseVertices.clear();\n\t\t\t\t}\n\t\t\t}\n\t\t\tint useVerticesN = useVertices.size();\n\t\t\tif (useVerticesN < 1)\n\t\t\t\tcontinue; \/\/to next material\n\t\t\t\/\/pick triangles\n\t\t\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\t\t\tTriangle01* pTR = pMB->triangles.at(tN);\n\t\t\t\tif (pTR->flag != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pTR->subjN != gsN)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pTR->materialN != mtN)\n\t\t\t\t\tcontinue;\n\t\t\t\t\/\/if here - make a copy\n\t\t\t\tTriangle01* pTR2 = new Triangle01(*pTR);\n\t\t\t\tuseTriangles.push_back(pTR2);\n\t\t\t\tpTR->flag = 1;\n\t\t\t}\n\t\t\trearrangeArraysForDrawJob(pMB, pMB->vertices, useVertices, useTriangles);\n\t\t\tbuildSingleDrawJob(pMT, useVertices, useTriangles);\n\t\t\taddedDJs++;\n\t\t\t\/\/clear all for next material\n\t\t\tfor (int i = 0; i < useVerticesN; i++)\n\t\t\t\tdelete useVertices.at(i);\n\t\t\tuseVertices.clear();\n\t\t\tint useTrianglesN = useTriangles.size();\n\t\t\tfor (int i = 0; i < useTrianglesN; i++)\n\t\t\t\tdelete useTriangles.at(i);\n\t\t\tuseTriangles.clear();\n\t\t}\n\t\tif (pGS != NULL)\n\t\t\tpGS->djTotalN = DrawJob::drawJobs.size() - pGS->djStartN;\n\t}\n\treturn addedDJs;\n}\n\nint ModelBuilder1base::buildSingleDrawJob(Material* pMT, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles) {\n\tint totalVertsN = useVertices.size();\n\tif (totalVertsN < 1)\n\t\treturn 0;\n\t\/\/if (pMT->uTex2nm >= 0)\n\t\/\/\tcalculateTangentSpace(useVertices, useTriangles);\n\tpMT->pickShaderNumber();\n\tDrawJob* pDJ = new DrawJob();\n\t\/\/copy material to DJ\n\tmemcpy(&pDJ->mt, pMT, sizeof(Material));\n\t\/\/calculate VBO element size (stride) and variables offsets in VBO\n\tint VBOid = DrawJob::newBufferId();\n\tint stride = 0;\n\tpDJ->setDesirableOffsets(&stride, pDJ->mt.shaderN, VBOid);\n\t\/\/create an array for VBO\n\tint bufferSize = totalVertsN * stride;\n\tfloat* vertsBuffer = new float[bufferSize];\n\t\/\/fill vertsBuffer\n\tShader* pSh = Shader::shaders.at(pDJ->mt.shaderN);\n\tint floatSize = sizeof(float);\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pVX = useVertices.at(vN);\n\t\tint idx = vN * stride \/ floatSize;\n\t\t\/\/pick data from vertex and move to the buffer\n\t\tmemcpy(&vertsBuffer[idx + pDJ->aPos.offset \/ floatSize], pVX->aPos, 3 * floatSize);\n\t\tif (pSh->l_aNormal >= 0) \/\/normal\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aNormal.offset \/ floatSize], pVX->aNormal, 3 * floatSize);\n\t\tif (pSh->l_aTuv >= 0) \/\/attribute TUV (texture coordinates)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aTuv.offset \/ floatSize], pVX->aTuv, 2 * floatSize);\n\t\tif (pSh->l_aTuv2 >= 0) \/\/attribute TUV2 (normal maps)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aTuv2.offset \/ floatSize], pVX->aTuv2, 2 * floatSize);\n\t\tif (pSh->l_aTangent >= 0)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aTangent.offset \/ floatSize], pVX->aTangent, 3 * floatSize);\n\t\tif (pSh->l_aBinormal >= 0)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aBinormal.offset \/ floatSize], pVX->aBinormal, 3 * floatSize);\n\t}\n\t\/\/buffer is ready, create VBO\n\tglBindBuffer(GL_ARRAY_BUFFER, VBOid);\n\tglBufferData(GL_ARRAY_BUFFER, bufferSize * floatSize, vertsBuffer, GL_STATIC_DRAW);\n\tdelete[] vertsBuffer;\n\tpDJ->pointsN = totalVertsN;\n\n\tint totalTrianglesN = useTriangles.size();\n\tif (totalTrianglesN > 0) {\n\t\t\/\/create EBO\n\t\tint totalIndexesN = totalTrianglesN * 3;\n\t\t\/\/create buffer\n\t\tGLushort* indexBuffer = new GLushort[totalIndexesN];\n\t\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\t\tTriangle01* pTR = useTriangles[tN];\n\t\t\tint idx = tN * 3;\n\t\t\tindexBuffer[idx] = (GLushort)pTR->idx[0];\n\t\t\tindexBuffer[idx + 1] = (GLushort)pTR->idx[1];\n\t\t\tindexBuffer[idx + 2] = (GLushort)pTR->idx[2];\n\t\t}\n\t\t\/\/buffer is ready, create IBO\n\t\tpDJ->glEBOid = DrawJob::newBufferId();\n\t\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pDJ->glEBOid);\n\t\tglBufferData(GL_ELEMENT_ARRAY_BUFFER, totalIndexesN * sizeof(GLushort), indexBuffer, GL_STATIC_DRAW);\n\t\tdelete[] indexBuffer;\n\t\tpDJ->pointsN = totalIndexesN;\n\t}\n\t\/\/create and fill vertex attributes array (VAO)\n\tpDJ->buildVAO();\n\treturn 1;\n}\n\nint ModelBuilder1base::rearrangeArraysForDrawJob(ModelBuilder1base* pMB, std::vector<Vertex01*> allVertices, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles) {\n\tint totalTrianglesN = useTriangles.size();\n\tif (totalTrianglesN < 1)\n\t\treturn 0;\n\tint totalVerticesN = useVertices.size();\n\t\/\/save new vertices order in original vertices array\n\t\/\/since triangles indices refer to original vertices order\n\tfor (int i = 0; i < totalVerticesN; i++) {\n\t\tVertex01* pVX1 = useVertices.at(i);\n\t\tVertex01* pVX0 = allVertices.at(pVX1->altN);\n\t\tpVX0->altN = i;\n\t}\n\t\/\/replace triangle original indices by new numbers saved in original vertices altN\n\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\tTriangle01* pTR = useTriangles.at(tN);\n\t\tfor (int i = 0; i < 3; i++) {\n\t\t\tVertex01* pVX0 = allVertices.at(pTR->idx[i]);\n\t\t\tpTR->idx[i] = pVX0->altN;\n\t\t}\n\t}\n\treturn 1;\n}\n\nint ModelBuilder1base::moveGroupDg(ModelBuilder1base* pMB, float aX, float aY, float aZ, float kX, float kY, float kZ) {\n\t\/\/moves and rotates vertex group\n\t\/\/rotation angles are set in degrees\n\tmat4x4 transformMatrix = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };\n\tmat4x4_translate(transformMatrix, kX, kY, kZ);\n\t\/\/rotation order: Z-X-Y\n\tif (aY != 0) mat4x4_rotate_Y(transformMatrix, transformMatrix, degrees2radians * aY);\n\tif (aX != 0) mat4x4_rotate_X(transformMatrix, transformMatrix, degrees2radians * aX);\n\tif (aZ != 0) mat4x4_rotate_Z(transformMatrix, transformMatrix, degrees2radians * aZ);\n\n\tint vertsN = pMB->vertices.size();\n\tfor (int i = pMB->pCurrentGroup->fromVertexN; i < vertsN; i++) {\n\t\tVertex01* pVX = pMB->vertices.at(i);\n\t\tmat4x4_mul_vec4plus(pVX->aPos, transformMatrix, pVX->aPos, 1);\n\t\tmat4x4_mul_vec4plus(pVX->aNormal, transformMatrix, pVX->aNormal, 0);\n\t}\n\treturn 1;\n}\nvoid ModelBuilder1base::lockGroup(ModelBuilder1base* pMB) {\n\tif (pMB->pCurrentGroup != NULL)\n\t\tpMB->groupsStack.push_back(pMB->pCurrentGroup);\n\tpMB->pCurrentGroup = new Group01();\n\tpMB->pCurrentGroup->fromVertexN = pMB->vertices.size();\n\tpMB->pCurrentGroup->fromTriangleN = pMB->triangles.size();\n}\nvoid ModelBuilder1base::releaseGroup(ModelBuilder1base* pMB) {\n\tif (pMB->groupsStack.size() > 0) {\n\t\tpMB->pCurrentGroup = pMB->groupsStack.back();\n\t\tpMB->groupsStack.pop_back();\n\t}\n\telse\n\t\tpMB->pCurrentGroup = NULL;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n
<\/p>\n\n\n\n
<\/p>\n\n\n\n