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\u041c\u044b \u0412\u0421\u0415 \u0415\u0429\u0415 \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f “\u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c” \u0441\u0442\u044b\u043a (\u0449\u0435\u043b\u044c) \u043c\u0435\u0436\u0434\u0443 \u043f\u0430\u0447\u043a\u043e\u0439 \u0438 \u043a\u0440\u044b\u0448\u043a\u043e\u0439 \u043a\u0430\u043a \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e normal map<\/em> \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u043a \u0447\u0430\u0441\u0442\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439<\/strong> \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438.<\/p>\n\n\n\n \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u044b\u0440\u0435\u0437\u0430\u043d\u043d\u044b\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b<\/em> \u0441 \u0438\u0445 “\u0440\u043e\u0434\u043d\u044b\u043c\u0438” \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u043c\u0438. \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0433\u043b\u0430\u0432\u0435 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u043b\u0438 \u0438\u0445 \u043d\u0430 \u0437\u0435\u043b\u0435\u043d\u044b\u0439 Phong. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0436\u0435 \u0434\u0435\u043b\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0440\u043e\u0434\u043d\u044b\u0435 <\/strong>Material-\u044b, \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 normal map<\/em>. \u0412\u043e\u0431\u0449\u0435\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c <\/strong>\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439<\/em> \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b.<\/p>\n\n\n\n \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f:<\/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 C:\\CPP\\a997modeler\\p_windows\\p_windows.sln<\/em>.<\/p>\n\n\n\n 2. \u041f\u043e\u0434 modeler <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 header file MaterialAdjust.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 3. \u041f\u043e\u0434 modeler <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 C++ file MaterialAdjust.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 \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432\u0435\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0438\u0437 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 Material <\/em>\u043f\u043b\u044e\u0441 2 \u043d\u043e\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n\n\n\n \u0412 root01.txt<\/em> \u0443 \u043d\u0430\u0441 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0433:<\/p>\n\n\n\n 4. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043d\u0438\u0436\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/strong> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e (overwrite) to\/as<\/p>\n\n\n\n C:\\CPP\\a997modeler<\/strong>\\dt\\models\\misc\\marlboro01\\root01.txt<\/strong><\/em><\/p>\n\n\n <\/p>\n\n\n\n \u0422\u0435\u043f\u0435\u0440\u044c – \u0447\u0442\u0435\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0442\u0430\u0433\u043e\u0432 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432:<\/p>\n\n\n\n 5. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelLoader.h<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 6. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelLoader.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n <\/p>\n\n\n\n \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 ModelLoader <\/em>\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 ModelBuilder<\/em>.<\/p>\n\n\n\n 7. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder1base.h<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 8. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder1base.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 9. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder.h<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 10. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n <\/p>\n\n\n\n 11. \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n\n\n\n \u0414\u043e:<\/strong><\/p>\n\n\n\n <\/p>\n\n\n\n \u041f\u043e\u0441\u043b\u0435:<\/strong><\/p>\n\n\n\n <\/p>\n\n\n\nWindows<\/h2>\n\n\n\n
\n\n\n\n\n#pragma once\n#include "Material.h"\n\nclass MaterialAdjust : public Material\n{\npublic:\n\tbool b_shaderType = false;\n\tbool b_primitiveType = false;\n\tbool b_uColor = false;\n\tbool b_uTex0 = false;\n\tbool b_uTex1mask = false;\n\tbool b_uTex2nm = false;\n\tbool b_uTex3 = false;\n\tbool b_uTex1alphaChannelN = false;\n\tbool b_uTex1alphaNegative = false;\n\tbool b_uTex0translateChannelN = false;\n\n\tbool b_uAlphaBlending = false;\n\tbool b_uAlphaFactor = false;\n\tbool b_uAmbient = false;\n\t\/\/specular light parameters\n\tbool b_uSpecularIntencity = false;\n\tbool b_uSpecularMinDot = false;\n\tbool b_uSpecularPowerOf = false;\npublic:\n\tstatic int adjust(Material* pMT, MaterialAdjust* pMA);\n\n\tstatic int setWhat2adjust(MaterialAdjust* pMA, std::string tagStr);\n};\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#include "MaterialAdjust.h"\n\nint MaterialAdjust::adjust(Material* pMT, MaterialAdjust* pMA) {\n\tif (pMA->b_shaderType)\n\t\tpMT->setShaderType(pMA->shaderType);\n\tif (pMA->b_primitiveType)\n\t\tpMT->primitiveType = pMA->primitiveType;\n\tif (pMA->b_uColor) {\n\t\tmemcpy(&pMT->uColor, &pMA->uColor, sizeof(MyColor));\n\t\tpMT->uTex0 = -1;\n\t}\n\tif (pMA->b_uTex0) {\n\t\tpMT->uTex0 = pMA->uTex0;\n\t\tpMT->uColor.setUint32(0);\n\t}\n\tif (pMA->b_uTex1mask)\n\t\tpMT->uTex1mask = pMA->uTex1mask;\n\tif (pMA->b_uTex2nm)\n\t\tpMT->uTex2nm = pMA->uTex2nm;\n\tif (pMA->b_uTex3)\n\t\tpMT->uTex3 = pMA->uTex3;\n\tif (pMA->b_uTex1alphaChannelN)\n\t\tpMT->uTex1alphaChannelN = pMA->uTex1alphaChannelN;\n\tif (pMA->b_uTex1alphaNegative)\n\t\tpMT->uTex1alphaNegative = pMA->uTex1alphaNegative;\n\tif (pMA->b_uTex0translateChannelN)\n\t\tpMT->uTex0translateChannelN = pMA->uTex0translateChannelN;\n\tif (pMA->b_uAlphaBlending)\n\t\tpMT->uAlphaBlending = pMA->uAlphaBlending;\n\tif (pMA->b_uAlphaFactor)\n\t\tpMT->uAlphaFactor = pMA->uAlphaFactor;\n\tif (pMA->b_uAmbient)\n\t\tpMT->uAmbient = pMA->uAmbient;\n\tif (pMA->b_uSpecularIntencity)\n\t\tpMT->uSpecularIntencity = pMA->uSpecularIntencity;\n\tif (pMA->b_uSpecularMinDot)\n\t\tpMT->uSpecularMinDot = pMA->uSpecularMinDot;\n\tif (pMA->b_uSpecularPowerOf)\n\t\tpMT->uSpecularPowerOf = pMA->uSpecularPowerOf;\n\treturn 1;\n}\nint MaterialAdjust::setWhat2adjust(MaterialAdjust* pMA, std::string tagStr) {\n\tif (tagStr.find("uTex0") != std::string::npos)\n\t\tif(pMA->uTex0 >= 0)\n\t\t\tpMA->b_uTex0 = true;\n\tif (tagStr.find("uTex1mask") != std::string::npos)\n\t\tpMA->b_uTex1mask = true;\n\tif (tagStr.find("uTex2nm") != std::string::npos)\n\t\tpMA->b_uTex2nm = true;\n\tif (tagStr.find("uTex3") != std::string::npos)\n\t\tpMA->b_uTex3 = true;\n\tif (tagStr.find("mt_type") != std::string::npos)\n\t\tpMA->b_shaderType = true;\n\tif (tagStr.find("uColor") != std::string::npos)\n\t\tpMA->b_uColor = true;\n\tif (tagStr.find("primitiveType") != std::string::npos)\n\t\tpMA->b_primitiveType = true;\n\tif (tagStr.find("uTex1alphaChannelN") != std::string::npos)\n\t\tpMA->b_uTex1alphaChannelN = true;\n\tif (tagStr.find("uTex0translateChannelN") != std::string::npos)\n\t\tpMA->b_uTex0translateChannelN = true;\n\tif (tagStr.find("uAlphaBlending") != std::string::npos)\n\t\tpMA->b_uAlphaBlending = true;\n\tif (tagStr.find("uAlphaFactor") != std::string::npos)\n\t\tpMA->b_uAlphaFactor = true;\n\tif (tagStr.find("uAmbient") != std::string::npos)\n\t\tpMA->b_uAmbient = true;\n\tif (tagStr.find("uSpecularIntencity") != std::string::npos)\n\t\tpMA->b_uSpecularIntencity = true;\n\tif (tagStr.find("uSpecularMinDot") != std::string::npos)\n\t\tpMA->b_uSpecularMinDot = true;\n\tif (tagStr.find("uSpecularPowerOf") != std::string::npos)\n\t\tpMA->b_uSpecularPowerOf = true;\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n<mt_adjust uTex2nm_use=\"tx0\" ><\/code><\/pre>\n\n\n\n\n<texture_as="tx0" src="marlboro03small.png" ckey="#00ff00"\/>\n<mt_type="phong" uTex0_use="tx0" \/>\n<vs="box_tank" whl="53,83,21" ext=1 sectR=1 \/>\n<a="front v" xywh="2,1,323,495" mark="box_front"\/>\n<a="back v" xywh="2,1,323,495" mark="box_back"\/>\n<a="right all" xywh="327,1,128,495" mark="box_right"\/>\n<a="left all" xywh="457,1,128,495" mark="box_left"\/>\n<a="top" xywh="588,1,323,133"\/>\n<a="bottom" xywh="587,136,324,134"\/>\n\/\/golden prints\n<vs="box" whl="55.1,85.1,23.1" \/>\n<texture_as="whitenoise" src="\/dt\/common\/img\/whitenoise\/wn64_blur3.bmp"\/>\n<texture_as="gold" src="\/dt\/common\/img\/materials\/gold02roman.bmp" \/>\n<mt_type="mirror" uAlphaBlending uTex1mask_use="tx0" uTex1alphaChannelN=1 uTex0_use="whitenoise" uTex0translateChannelN=0 uTex3_use="gold" \/>\n\/\/side golden prints\n<a="right" xywh="342,12,101,10" whl="x,1.8,18.1" pxyz="x,39.8, -0.3" \/> \/\/Please do not litter\n<a="right" xywh="339,144,105,89" whl="x,15.35,18.9" pxyz="x,10.3,-0.12" \/> \/\/For special offers...\n<a="left" xywh="475,15,95,48" whl="x,8.4,17" pxyz="x,36, 0.3" \/> \/\/Underage sale...\n\/\/front prints\n<group>\n\t\/\/bottom golden print "20 class a..."\n\t<a="front" xywh="20,498,289,13" whl="47.5,2,x" pxyz="1,-36,x" \/>\n\t\/\/blazon\/emblem\n\t<mt_type="mirror" uAlphaBlending uTex2nm_use="tx0" uTex0_use="whitenoise" uTex0translateChannelN=0 uTex3_use="gold" \/>\n\t<a="front" xywh2nm="589,415,128,94" whl="20.7,16,x" pxyz="0.3,6.1,x" \/> \/\/emblem\n\t\/\/"Marlboro\n\t<mt_type="phong" uAlphaBlending uTex2nm_use="tx0" uColor="#1E211E" \/>\n\t<a="front" xywh2nm="590,275,301,136" whl="49.2,23.3,x" pxyz="0.21,-18,x" \/> \/\/marlboro\n<\/group> \n<clone ay=180 \/>\n\/\/joint (slit) between the pack and the lid\n<group>\n\t<mt_adjust uTex2nm_use="tx0" >\n\t\t<a2mesh wh="50,1" xywh2nm="582,497,1,4" all markedAs="box_right" onThe="right" py=24.6 az=31 \/>\n\t\t<a2mesh wh="50,1" xywh2nm="582,497,1,4" all markedAs="box_left" onThe="left" py=24.6 az=-31 \/>\n\t\t<a2mesh wh="53,1" xywh2nm="582,497,1,4" all markedAs="box_front" py=17.8 \/>\n\t\t<a2mesh wh="6 ,1" xywh2nm="582,497,1,4" all markedAs="box_back" onThe="back" py=31.5 px=23.5 \/>\n\t\t<a2mesh wh="6 ,1" xywh2nm="582,497,1,4" all markedAs="box_back" onThe="back" py=31.5 px=-23.5 \/>\n\t<\/mt_adjust> \n<\/group sizeD="0.1,0,0.1"> \n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#pragma once\n#include "XMLparser.h"\n#include "ModelBuilder.h"\n#include "GroupTransform.h"\n#include "MaterialAdjust.h"\n\nclass ModelLoader : public XMLparser\n{\npublic:\n\tModelBuilder* pModelBuilder = NULL;\n\tbool ownModelBuilder = false;\n\tstd::vector<GameSubj*>* pSubjsVector = NULL;\n\tMaterialAdjust* pMaterialAdjust = 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\tpModelBuilder->lockGroup(pModelBuilder);\n\t\t}\n\t\tpModelBuilder->useSubjN(pModelBuilder,subjN);\n\t};\n\tvirtual ~ModelLoader() {\n\t\tif (!ownModelBuilder)\n\t\t\treturn;\n\t\tpModelBuilder->buildDrawJobs(pModelBuilder, *pSubjsVector);\n\t\tdelete pModelBuilder;\n\t};\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_vs(VirtualShape* pVS, std::string tagStr); \/\/virtual shape\n\tstatic int fillProps_mt(Material* pMT, std::string tagStr, ModelLoader* pML); \/\/Material\n\tstatic int fillProps_gt(GroupTransform* pGS, ModelBuilder* pMB, std::string tagStr);\n\tvirtual int 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\tstatic int processTag_clone(ModelLoader* pML);\n\tstatic int addMark(char* marks, std::string newMark);\n\tstatic int processTag_do(ModelLoader* pML);\n\tstatic int processTag_a2mesh(ModelLoader* pML);\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#include "Polygon.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}\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\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.compare("mt_type") == 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\tfillProps_mt(&mt, pML->currentTag, pML);\n\t\tpMB->usingMaterialN = pMB->getMaterialN(pMB, &mt);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/mt_type") == 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\t\/\/mark\n\t\tif (varExists("mark", pML->currentTag))\n\t\t\taddMark(pMB->pCurrentGroup->marks, getStringValue("mark", pML->currentTag));\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/group") == 0) {\n\t\tGroupTransform gt;\n\t\tfillProps_gt(>, pMB, pML->currentTag);\n\t\tgt.executeGroupTransform(pMB);\n\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\tif (pML->tagName.compare("clone") == 0)\n\t\treturn processTag_clone(pML);\n\tif (pML->tagName.compare("\/clone") == 0)\n\t\treturn processTag_clone(pML);\n\tif (pML->tagName.compare("do") == 0)\n\t\treturn processTag_do(pML);\n\tif (pML->tagName.compare("a2mesh") == 0)\n\t\treturn processTag_a2mesh(pML);\n\tif (pML->tagName.compare("mt_adjust") == 0) {\n\t\tif (pML->pMaterialAdjust != NULL)\n\t\t\tmylog("ERROR in ModelLoader::processTag %s, pMaterialAdjust is still busy. File: %s\\n", pML->currentTag.c_str(), pML->fullPath.c_str());\n\t\tpML->pMaterialAdjust = new (MaterialAdjust);\n\t\tfillProps_mt(pML->pMaterialAdjust, pML->currentTag, pML);\n\t\tpML->pMaterialAdjust->setWhat2adjust(pML->pMaterialAdjust, pML->currentTag);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/mt_adjust") == 0) {\n\t\tif (pML->pMaterialAdjust != NULL) {\n\t\t\tdelete pML->pMaterialAdjust;\n\t\t\tpML->pMaterialAdjust = NULL;\n\t\t}\n\t\treturn 1;\n\t}\n\n\t\/\/mylog("%s, %s \/group?=%d\\n",pML->currentTag.c_str(), pML->tagName.c_str(), (pML->tagName.compare("\/group") == 0));\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}\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\t\/\/mark\n\tif (varExists("mark", tagStr))\n\t\taddMark(pMB->pCurrentGroup->marks, getStringValue("mark", tagStr));\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\tTexCoords* pTC = NULL;\n\tif (varExists("xywh", tagStr)) {\n\t\tsetFloatArray(xywh, 4, "xywh", tagStr);\n\t\tstd::string flipStr = getStringValue("flip", tagStr);\n\t\tTexCoords tc;\n\t\ttc.set(texN, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\tpTC = &tc;\n\t}\n\tTexCoords* pTC2nm = NULL;\n\tif (varExists("xywh2nm", tagStr)) {\n\t\tsetFloatArray(xywh, 4, "xywh2nm", tagStr);\n\t\tstd::string flipStr = getStringValue("flip2nm", tagStr);\n\t\tTexCoords tc2nm;\n\t\ttc2nm.set(pMT->uTex2nm, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\tpTC2nm = &tc2nm;\n\t}\n\t\/\/adjusted VirtualShape\n\tVirtualShape* pVS_a = new VirtualShape(*pMB->pCurrentVShape);\n\tfillProps_vs(pVS_a, tagStr);\n\n\tfor (int aN = 0; aN < (int)applyTosVector.size(); aN++) {\n\t\tpMB->buildFace(pMB, applyTosVector.at(aN), pVS_a, pTC, pTC2nm);\n\t}\n\tdelete pVS_a;\n\t\/\/mylog("vertsN=%d\\n",pMB->vertices.size());\n\n\tGroupTransform GT_a;\n\tfillProps_gt(>_a, pMB, tagStr);\n\tGT_a.executeGroupTransform(pMB);\n\n\tpMB->releaseGroup(pMB);\n\treturn 1;\n}\nint ModelLoader::processTag_clone(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tif (pML->tagName.compare("clone") == 0) {\n\t\t\/\/mark what to clone\n\t\tGroupTransform gt;\n\t\tgt.pGroup = pMB->pLastClosedGroup;\n\t\tgt.flagSelection(>, &pMB->vertices, &pMB->triangles);\n\n\t\t\/\/cloning\n\t\tpMB->lockGroup(pMB);\n\t\tgt.cloneFlagged(pMB, &pMB->vertices, &pMB->triangles, &pMB->vertices, &pMB->triangles);\n\t}\n\tGroupTransform gt;\n\tfillProps_gt(>, pMB, pML->currentTag);\n\tgt.executeGroupTransform(pMB);\n\n\tif (pML->tagName.compare("\/clone") == 0 || pML->closedTag) {\n\t\tpMB->releaseGroup(pMB);\n\t}\n\treturn 1;\n}\nint ModelLoader::addMark(char* marks, std::string newMark) {\n\tif (newMark.empty())\n\t\treturn 0;\n\tstd::string allMarks;\n\tallMarks.assign(marks);\n\tallMarks.append("<" + newMark + ">");\n\tmyStrcpy_s(marks, 124, allMarks.c_str());\n\treturn 1;\n}\nint ModelLoader::fillProps_gt(GroupTransform* pGT, ModelBuilder* pMB, std::string tagStr) {\n\tpGT->pGroup = pMB->pCurrentGroup;\n\t\/\/position\n\tsetFloatArray(pGT->shift, 3, "pxyz", tagStr);\n\tsetFloatValue(&pGT->shift[0], "px", tagStr);\n\tsetFloatValue(&pGT->shift[1], "py", tagStr);\n\tsetFloatValue(&pGT->shift[2], "pz", tagStr);\n\t\/\/angles\n\tsetFloatArray(pGT->spin, 3, "axyz", tagStr);\n\tsetFloatValue(&pGT->spin[0], "ax", tagStr);\n\tsetFloatValue(&pGT->spin[1], "ay", tagStr);\n\tsetFloatValue(&pGT->spin[2], "az", tagStr);\n\t\/\/scale\n\tsetFloatArray(pGT->scale, 3, "scale", tagStr);\n\n\tpGT->onThe = getStringValue("onThe", tagStr);\n\tpGT->allign = getStringValue("allign", tagStr);\n\tpGT->headZto = getStringValue("headZto", tagStr);\n\t\/\/limit to\n\tif (varExists("all", tagStr))\n\t\tpGT->pGroup = NULL;\n\tif (varExists("lastClosedGroup", tagStr))\n\t\tpGT->pGroup = pMB->pLastClosedGroup;\n\tif (varExists("markedAs", tagStr))\n\t\tpGT->limit2mark(pGT, getStringValue("markedAs", tagStr));\n\tsetFloatArray(pGT->pMin, 3, "xyzMin", tagStr);\n\tsetFloatArray(pGT->pMax, 3, "xyzMax", tagStr);\n\n\tif (varExists("sizeD", tagStr)) { \/\/re-size\n\t\tfloat sizeD[3];\n\t\tsetFloatArray(sizeD, 3, "sizeD", tagStr);\n\t\t\/\/bounding box\n\t\tpGT->flagSelection(pGT, &pMB->vertices, NULL);\n\t\tfloat bbMin[3];\n\t\tfloat bbMax[3];\n\t\tpGT->buildBoundingBoxFlagged(bbMin, bbMax, &pMB->vertices);\n\t\tfor (int i = 0; i < 3; i++) {\n\t\t\tfloat size = bbMax[i] - bbMin[i];\n\t\t\tpGT->scale[i] = (size + sizeD[i]) \/ size;\n\t\t}\n\t}\n\treturn 1;\n}\nint ModelLoader::processTag_do(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tGroupTransform gt;\n\tfillProps_gt(>, pMB, pML->currentTag);\n\tgt.flagSelection(>, &pMB->vertices, &pMB->triangles);\n\tgt.transformFlagged(>, &pMB->vertices);\n\treturn 1;\n}\nint ModelLoader::processTag_a2mesh(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tstd::string tagStr = pML->currentTag;\n\tGroupTransform gt;\n\tfillProps_gt(>, pMB, pML->currentTag);\n\tgt.flagSelection(>, &pMB->vertices, &pMB->triangles);\n\t\/\/clone a copy\n\tstd::vector<Vertex01*> vx1;\n\tstd::vector<Triangle01*> tr1;\n\tgt.cloneFlagged(NULL, &vx1, &tr1, &pMB->vertices, &pMB->triangles);\n\t\/\/ build transform and inverted martrices\n\tmat4x4 transformMatrix;\n\tgt.buildTransformMatrix(>, &transformMatrix);\n\tmat4x4 transformMatrixInverted;\n\tmat4x4_invert(transformMatrixInverted, transformMatrix);\n\t\/\/move\/rotate cloned\n\tgt.flagAll(&vx1, &tr1);\n\t\/\/gt.transformFlagged(&pMB->vertices, &transformMatrixInverted);\n\tgt.transformFlaggedMx(&vx1, &transformMatrixInverted);\n\n\t\/\/gt.cloneFlagged(pMB, &pMB->vertices, &pMB->triangles, &vx1, &tr1);\n\n\tfloat wh[2];\n\tsetFloatArray(wh, 2, "wh", tagStr);\n\tPolygon frame;\n\tframe.setRectangle(&frame, wh[0], wh[1]);\n\t\/\/destination arrays\n\tstd::vector<Vertex01*> vx2;\n\tstd::vector<Triangle01*> tr2;\n\tPolygon triangle;\n\tfor (int i = tr1.size() - 1; i >= 0; i--) {\n\t\ttriangle.setTriangle(&triangle, tr1.at(i), &vx1);\n\t\tPolygon intersection;\n\t\tint pointsN = Polygon::xyIntersection(&intersection, &frame, &triangle);\n\t\tif (pointsN > 2) {\n\t\t\tPolygon::buildTriangles(&intersection);\n\t\t\tGroupTransform::flagAll(&intersection.vertices, &intersection.triangles);\n\t\t\tGroupTransform::cloneFlagged(NULL, &vx2, &tr2, &intersection.vertices, &intersection.triangles);\n\t\t}\n\t}\n\tgt.flagAll(&vx2, &tr2);\n\t\/\/at this point we have cutted fragment facing us\n\tint vxTotal = vx2.size();\n\tint trTotal = tr2.size();\n\t\/\/apply adjusted material ?\n\tif (pML->pMaterialAdjust != NULL) {\n\t\t\/\/scan vertices to find new (unupdated) material\n\t\tint materialNsrc = -1; \/\/which N to replace\n\t\tint materialNdst = -1; \/\/replace by N \n\t\tfor (int vN = 0; vN < vxTotal; vN++) {\n\t\t\tVertex01* pV = vx2.at(vN);\n\t\t\tif (pV->flag < 0)\n\t\t\t\tcontinue;\n\t\t\tif (materialNsrc == pV->materialN)\n\t\t\t\tcontinue;\n\t\t\t\/\/have new material\n\t\t\tmaterialNsrc = pV->materialN;\n\t\t\tMaterial mt;\n\t\t\tMaterial* pMt0 = pMB->materialsList.at(materialNsrc);\n\t\t\tmemcpy(&mt, pMt0, sizeof(Material));\n\t\t\t\/\/modify material\n\t\t\tMaterialAdjust::adjust(&mt, pML->pMaterialAdjust);\n\t\t\tmaterialNdst = pMB->getMaterialN(pMB, &mt);\n\t\t\tif (materialNsrc != materialNdst) {\n\t\t\t\t\/\/replace mtN in vx and tr arrays\n\t\t\t\tfor (int vN2 = vN; vN2 < vxTotal; vN2++) {\n\t\t\t\t\tVertex01* pV2 = vx2.at(vN2);\n\t\t\t\t\tif (pV2->flag < 0)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (materialNsrc == pV2->materialN)\n\t\t\t\t\t\tpV2->materialN = materialNdst;\n\t\t\t\t}\n\t\t\t\tfor (int tN2 = 0; tN2 < trTotal; tN2++) {\n\t\t\t\t\tTriangle01* pT2 = tr2.at(tN2);\n\t\t\t\t\tif (pT2->flag < 0)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (materialNsrc == pT2->materialN)\n\t\t\t\t\t\tpT2->materialN = materialNdst;\n\t\t\t\t}\n\t\t\t\tmaterialNsrc = materialNdst;\n\t\t\t}\n\t\t}\n\t}\n\telse { \/\/ pML->pMaterialAdjust == NULL, use pMB->usingMaterialN\n\t\tfor (int vN2 = 0; vN2 < vxTotal; vN2++) {\n\t\t\tVertex01* pV2 = vx2.at(vN2);\n\t\t\tif (pV2->flag < 0)\n\t\t\t\tcontinue;\n\t\t\tpV2->materialN = pMB->usingMaterialN;\n\t\t}\n\t\tfor (int tN2 = 0; tN2 < trTotal; tN2++) {\n\t\t\tTriangle01* pT2 = tr2.at(tN2);\n\t\t\tif (pT2->flag < 0)\n\t\t\t\tcontinue;\n\t\t\tpT2->materialN = pMB->usingMaterialN;\n\t\t}\n\t}\n\t\/\/apply xywh\/2nm ?\n\tif (varExists("xywh", tagStr) || varExists("xywh2nm", tagStr)) {\n\t\tMaterial* pMT = pMB->materialsList.at(vx2.at(0)->materialN);\n\t\tfloat xywh[4] = { 0,0,1,1 };\n\t\tTexCoords* pTC = NULL;\n\t\tif (varExists("xywh", tagStr)) {\n\t\t\tsetFloatArray(xywh, 4, "xywh", tagStr);\n\t\t\tstd::string flipStr = getStringValue("flip", tagStr);\n\t\t\tint texN = pMT->uTex1mask;\n\t\t\tif (texN < 0)\n\t\t\t\ttexN = pMT->uTex0;\n\t\t\tTexCoords tc;\n\t\t\ttc.set(texN, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\t\tpTC = &tc;\n\t\t}\n\t\tTexCoords* pTC2nm = NULL;\n\n\t\tif (varExists("xywh2nm", tagStr)) {\n\t\t\tsetFloatArray(xywh, 4, "xywh2nm", tagStr);\n\t\t\tstd::string flipStr = getStringValue("flip2nm", tagStr);\n\t\t\tTexCoords tc2nm;\n\t\t\ttc2nm.set(pMT->uTex2nm, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\t\tpTC2nm = &tc2nm;\n\t\t}\n\t\tpMB->applyTexture2flagged(&vx2, "front", pTC, false);\n\t\tpMB->applyTexture2flagged(&vx2, "front", pTC2nm, true);\n\t}\n\t\/\/move\/rotate\n\tgt.transformFlaggedMx(&vx2, &transformMatrix);\n\t\/\/clone back to modelBuilder arrays\n\tgt.cloneFlagged(pMB, &pMB->vertices, &pMB->triangles, &vx2, &tr2);\n\n\t\/\/clear memory\n\tfor (int i = vx1.size() - 1; i >= 0; i--)\n\t\tdelete vx1.at(i);\n\tvx1.clear();\n\tfor (int i = tr1.size() - 1; i >= 0; i--)\n\t\tdelete tr1.at(i);\n\ttr1.clear();\n\tfor (int i = vx2.size() - 1; i >= 0; i--)\n\t\tdelete vx2.at(i);\n\tvx2.clear();\n\tfor (int i = tr2.size() - 1; i >= 0; i--)\n\t\tdelete tr2.at(i);\n\ttr2.clear();\n\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\tGroup01* pLastClosedGroup = NULL;\n\t\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\tstatic int useSubjN(ModelBuilder1base* pMB, int subjN);\n\tstatic int getMaterialN(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\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\tstatic int calculateTangentSpace(std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles);\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\treleaseGroup(this);\n\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\tif (pCurrentGroup != NULL)\n\t\tdelete pCurrentGroup;\n\tif (pLastClosedGroup != NULL)\n\t\tdelete pLastClosedGroup;\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::getMaterialN(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\treturn i;\n\t\t\t}\n\t\/\/if here - add new material 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\t\/\/mark\n\tif (pMB->pCurrentGroup != NULL)\n\t\tif (strcmp(pMB->pCurrentGroup->marks, "") != 0)\n\t\t\tmyStrcpy_s(pTR->marks, 124, pMB->pCurrentGroup->marks);\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\t\/\/mark\n\tif (pMB->pCurrentGroup != NULL)\n\t\tif (strcmp(pMB->pCurrentGroup->marks, "") != 0)\n\t\t\tmyStrcpy_s(pVX->marks, 124, pMB->pCurrentGroup->marks);\n\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\tif (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}\n\nint ModelBuilder1base::calculateTangentSpace(std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles) {\n\tint totalVertsN = useVertices.size();\n\tif (totalVertsN < 1)\n\t\treturn 0;\n\tint totalTrianglesN = useTriangles.size();\n\t\/\/assuming that GL_TRIANGLES\n\t\/\/clear flags\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pV = useVertices.at(vN);\n\t\tpV->flag = 0;\n\t}\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pVX = useVertices.at(vN);\n\t\tif (pVX->flag != 0)\n\t\t\tcontinue;\n\t\tTriangle01* pT = NULL;\n\t\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\t\tpT = useTriangles.at(tN);\n\t\t\tbool haveTriangle = false;\n\t\t\tfor (int i = 0; i < 3; i++)\n\t\t\t\tif (pT->idx[i] == vN) {\n\t\t\t\t\thaveTriangle = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\tif (haveTriangle)\n\t\t\t\tbreak;\n\t\t}\n\t\tVertex01* pV[3];\n\t\tfor (int i = 0; i < 3; i++)\n\t\t\tpV[i] = useVertices.at(pT->idx[i]);\n\n\t\tfloat dPos1[3];\n\t\tfloat dPos2[3];\n\t\tfloat dUV1[2];\n\t\tfloat dUV2[2];\n\t\tfor (int i = 0; i < 3; i++) {\n\t\t\tdPos1[i] = pV[1]->aPos[i] - pV[0]->aPos[i];\n\t\t\tdPos2[i] = pV[2]->aPos[i] - pV[0]->aPos[i];\n\t\t}\n\t\tfor (int i = 0; i < 2; i++) {\n\t\t\tdUV1[i] = pV[1]->aTuv2[i] - pV[0]->aTuv2[i];\n\t\t\tdUV2[i] = pV[2]->aTuv2[i] - pV[0]->aTuv2[i];\n\t\t}\n\n\t\tfloat tangent[3];\n\t\tfloat binormal[3];\n\t\tfloat divider = dUV1[0] * dUV2[1] - dUV1[1] * dUV2[0];\n\t\tif (divider == 0) {\n\t\t\tv3set(tangent, 1, 0, 0);\n\t\t\tv3set(binormal, 0, -1, 0);\n\t\t}\n\t\telse {\n\t\t\tfloat r = 1.0f \/ divider;\n\t\t\tfor (int i = 0; i < 3; i++) {\n\t\t\t\ttangent[i] = (dPos1[i] * dUV2[1] - dPos2[i] * dUV1[1]) * r;\n\t\t\t\tbinormal[i] = -(dPos2[i] * dUV1[0] - dPos1[i] * dUV2[0]) * r;\n\t\t\t}\n\t\t\tvec3_norm(tangent, tangent);\n\t\t\tvec3_norm(binormal, binormal);\n\t\t}\n\t\t\/\/add to all 3 vertices\n\t\tfor (int n = 0; n < 3; n++) {\n\t\t\tif (pV[n]->flag > 0)\n\t\t\t\tcontinue;\n\t\t\tv3copy(pV[n]->aTangent, tangent);\n\t\t\tv3copy(pV[n]->aBinormal, binormal);\n\t\t\tpV[n]->flag = 1;\n\t\t}\n\t}\n\t\/\/normalize tangent and binormal around normal\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pV = useVertices.at(vN);\n\t\tfloat v3out[3];\n\t\t\/\/tangent\n\t\tvec3_mul_cross(v3out, pV->aNormal, pV->aBinormal);\n\t\tif (v3dotProduct(pV->aTangent, v3out) < 0)\n\t\t\tv3inverse(v3out);\n\t\tv3copy(pV->aTangent, v3out);\n\t\t\/\/binormal\n\t\tvec3_mul_cross(v3out, pV->aNormal, pV->aTangent);\n\t\tif (v3dotProduct(pV->aBinormal, v3out) < 0)\n\t\t\tv3inverse(v3out);\n\t\tv3copy(pV->aBinormal, v3out);\n\t}\n\treturn 1;\n}\nvoid ModelBuilder1base::lockGroup(ModelBuilder1base* pMB) {\n\tGroup01* pPrevGroup = pMB->pCurrentGroup;\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\t\/\/marks\n\tif(pPrevGroup != NULL)\n\t\tif (strcmp(pPrevGroup->marks, "") != 0)\n\t\t\tmyStrcpy_s(pMB->pCurrentGroup->marks, 124, pPrevGroup->marks);\n}\nvoid ModelBuilder1base::releaseGroup(ModelBuilder1base* pMB) {\n\tif (pMB->pLastClosedGroup != NULL)\n\t\tdelete pMB->pLastClosedGroup;\n\tpMB->pLastClosedGroup = pMB->pCurrentGroup;\n\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\n#pragma once\n#include "ModelBuilder1base.h"\n#include "TexCoords.h"\n\nclass ModelBuilder : public ModelBuilder1base\n{\npublic:\n\tvirtual ~ModelBuilder();\n\tstatic int buildFace(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS, TexCoords* pTC = NULL, TexCoords* pTC2nm = NULL);\n\tstatic int buildBoxFace(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS, TexCoords* pTC = NULL, TexCoords* pTC2nm = NULL);\n\tstatic int buildBoxFacePlain(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS);\n\tstatic int buildBoxFaceTank(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS);\n\tstatic int cylinderWrap(ModelBuilder* pMB, VirtualShape* pVS, float angleFrom, float angleTo);\n\tstatic int capWrap(ModelBuilder* pMB, VirtualShape* pVS, float angleFrom, float angleTo);\n\tstatic int groupApplyTexture(ModelBuilder* pMB, std::string applyTo, TexCoords* pTC, TexCoords* pTC2nm = NULL);\n\tstatic int applyTexture2flagged(std::vector<Vertex01*>* pVX, std::string applyTo, TexCoords* pTC, bool isNormalMap);\n};\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#include "ModelBuilder.h"\n#include "platform.h"\n#include "utils.h"\n#include "DrawJob.h"\n#include "Shader.h"\n\nextern float degrees2radians;\n\nModelBuilder::~ModelBuilder() {\n}\n\nint ModelBuilder::buildFace(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS, TexCoords* pTC, TexCoords* pTC2nm) {\n\tif (strstr(pVS->shapeType, "box") == pVS->shapeType)\n\t\treturn buildBoxFace(pMB, applyTo, pVS, pTC, pTC2nm);\n\treturn -1;\n}\nint ModelBuilder::buildBoxFace(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS, TexCoords* pTC, TexCoords* pTC2nm) {\n\t\/\/this code is for simple box\n\tVirtualShape vs; \/\/face VS, \n\tmat4x4 transformMatrix = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };\n\tvs.sectionsR = pVS->sectionsR;\n\t\/\/rotate desirable side to face us. \n\tif (applyTo.find("front") == 0) {\n\t\t\/\/Side <front> is facing us as is.\n\t\tvs.whl[0] = pVS->whl[0];\n\t\tvs.whl[1] = pVS->whl[1];\n\t\tvs.sections[0] = pVS->sections[0];\n\t\tvs.sections[1] = pVS->sections[1];\n\t\t\/\/extensions\n\t\tvs.extF = pVS->extF;\n\t\tvs.extL = pVS->extL;\n\t\tvs.extR = pVS->extR;\n\t\tvs.extU = pVS->extU;\n\t\tvs.extD = pVS->extD;\n\t\t\/\/define how to move\/place generated face back to the VirtualShape\n\t\t\/\/just shift closer to us by length\/2\n\t\tmat4x4_translate(transformMatrix, 0, 0, pVS->whl[2] \/ 2);\n\t}\n\telse if (applyTo.find("back") == 0) {\n\t\tvs.whl[0] = pVS->whl[0];\n\t\tvs.whl[1] = pVS->whl[1];\n\t\tvs.sections[0] = pVS->sections[0];\n\t\tvs.sections[1] = pVS->sections[1];\n\t\t\/\/extensions\n\t\tvs.extF = pVS->extB;\n\t\tvs.extL = pVS->extR;\n\t\tvs.extR = pVS->extL;\n\t\tvs.extU = pVS->extU;\n\t\tvs.extD = pVS->extD;\n\t\t\/\/rotate 180 degrees around Y and shift farther from us by half-length\n\t\tmat4x4_translate(transformMatrix, 0, 0, -pVS->whl[2] \/ 2);\n\t\tmat4x4_rotate_Y(transformMatrix, transformMatrix, degrees2radians * 180);\n\t}\n\telse if (applyTo.find("left") == 0) {\n\t\tvs.whl[0] = pVS->whl[2]; \/\/width = original length\n\t\tvs.whl[1] = pVS->whl[1];\n\t\tvs.sections[0] = pVS->sections[2];\n\t\tvs.sections[1] = pVS->sections[1];\n\t\t\/\/extensions\n\t\tvs.extF = pVS->extL;\n\t\tvs.extL = pVS->extB;\n\t\tvs.extR = pVS->extF;\n\t\tvs.extU = pVS->extU;\n\t\tvs.extD = pVS->extD;\n\t\t\/\/rotate -90 degrees around Y (CW) and shift half-width to the left\n\t\tmat4x4_translate(transformMatrix, -pVS->whl[0] \/ 2, 0, 0);\n\t\tmat4x4_rotate_Y(transformMatrix, transformMatrix, -degrees2radians * 90);\n\t}\n\telse if (applyTo.find("right") == 0) {\n\t\tvs.whl[0] = pVS->whl[2]; \/\/width = original length\n\t\tvs.whl[1] = pVS->whl[1];\n\t\tvs.sections[0] = pVS->sections[2];\n\t\tvs.sections[1] = pVS->sections[1];\n\t\t\/\/extensions\n\t\tvs.extF = pVS->extR;\n\t\tvs.extL = pVS->extF;\n\t\tvs.extR = pVS->extB;\n\t\tvs.extU = pVS->extU;\n\t\tvs.extD = pVS->extD;\n\t\t\/\/rotate +90 degrees around Y (CCW) and shift half-width to the right\n\t\tmat4x4_translate(transformMatrix, pVS->whl[0] \/ 2, 0, 0);\n\t\tmat4x4_rotate_Y(transformMatrix, transformMatrix, degrees2radians * 90);\n\t}\n\telse if (applyTo.find("top") == 0) {\n\t\tvs.whl[0] = pVS->whl[0];\n\t\tvs.whl[1] = pVS->whl[2]; \/\/height = original length\n\t\tvs.sections[0] = pVS->sections[0];\n\t\tvs.sections[1] = pVS->sections[2];\n\t\t\/\/extensions\n\t\tvs.extF = pVS->extU;\n\t\tvs.extL = pVS->extR;\n\t\tvs.extR = pVS->extL;\n\t\tvs.extU = pVS->extF;\n\t\tvs.extD = pVS->extB;\n\t\t\/\/rotate -90 degrees around X (CW) and 180 around Y, and shift half-height up\n\t\tmat4x4_translate(transformMatrix, 0, pVS->whl[1] \/ 2, 0);\n\t\tmat4x4_rotate_Y(transformMatrix, transformMatrix, degrees2radians * 180);\n\t\tmat4x4_rotate_X(transformMatrix, transformMatrix, -degrees2radians * 90);\n\t}\n\telse if (applyTo.find("bottom") == 0) {\n\t\tvs.whl[0] = pVS->whl[0];\n\t\tvs.whl[1] = pVS->whl[2]; \/\/height = original length\n\t\tvs.sections[0] = pVS->sections[0];\n\t\tvs.sections[1] = pVS->sections[2];\n\t\t\/\/extensions\n\t\tvs.extF = pVS->extD;\n\t\tvs.extL = pVS->extL;\n\t\tvs.extR = pVS->extR;\n\t\tvs.extU = pVS->extF;\n\t\tvs.extD = pVS->extB;\n\t\t\/\/rotate 90 around X (CCW) and shift half-height down\n\t\tmat4x4_translate(transformMatrix, 0, -pVS->whl[1] \/ 2, 0);\n\t\tmat4x4_rotate_X(transformMatrix, transformMatrix, degrees2radians * 90);\n\t}\n\tlockGroup(pMB);\n\t\/\/create vertices\n\tif (strstr(pVS->shapeType, "tank") != nullptr)\n\t\tbuildBoxFaceTank(pMB, applyTo, &vs);\n\telse\n\t\tbuildBoxFacePlain(pMB, applyTo, &vs);\n\n\tgroupApplyTexture(pMB, "front", pTC, pTC2nm);\n\n\t\/\/move face to it's place (apply transform matrix)\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\treleaseGroup(pMB);\n\treturn 1;\n}\nint ModelBuilder::buildBoxFacePlain(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS) {\n\tif (pVS->whl[0] == 0 || pVS->whl[1] == 0)\n\t\treturn 0;\n\t\/\/create vertices\n\tint sectionsX = pVS->sections[0];\n\tint sectionsY = pVS->sections[1];\n\tint pointsX = sectionsX + 1;\n\tint pointsY = sectionsY + 1;\n\tfloat stepX = pVS->whl[0] \/ sectionsX;\n\tfloat stepY = pVS->whl[1] \/ sectionsY;\n\tfloat kY = pVS->whl[1] \/ 2;\n\tfor (int iy = 0; iy < pointsY; iy++) {\n\t\tfloat kX = -pVS->whl[0] \/ 2;\n\t\tfor (int ix = 0; ix < pointsX; ix++) {\n\t\t\tint nSE = addVertex(pMB, kX, kY, pVS->extF, 0, 0, 1); \/\/vertex number on south-east\n\t\t\tif (iy > 0 && ix > 0) {\n\t\t\t\t\/\/add 2 triangles\n\t\t\t\tint nSW = nSE - 1; \/\/vertex number south-west\n\t\t\t\tint nNE = nSE - pointsX; \/\/north-east\n\t\t\t\tint nNW = nSW - pointsX; \/\/north-west\n\t\t\t\tadd2triangles(pMB, nNW, nNE, nSW, nSE, iy + ix);\n\t\t\t}\n\t\t\tkX += stepX;\n\t\t}\n\t\tkY -= stepY;\n\t}\n\treturn 1;\n}\nint ModelBuilder::buildBoxFaceTank(ModelBuilder* pMB, std::string applyTo, VirtualShape* pVS) {\n\t\/\/for diamond effect - sectionsRad=1, don't merge normals\n\tbool drawMiddle = true;\n\t\/\/edges\n\tbool drawTop = false;\n\tbool drawBottom = false;\n\tbool drawLeft = false;\n\tbool drawRight = false;\n\t\/\/corners\n\tbool drawTopLeft = false;\n\tbool drawTopRight = false;\n\tbool drawBottomLeft = false;\n\tbool drawBottomRight = false;\n\tif (pVS->extF == 0 || applyTo.find(" all") != std::string::npos) {\n\t\tdrawTop = true;\n\t\tdrawBottom = true;\n\t\tdrawLeft = true;\n\t\tdrawRight = true;\n\t\tdrawTopLeft = true;\n\t\tdrawTopRight = true;\n\t\tdrawBottomLeft = true;\n\t\tdrawBottomRight = true;\n\t}\n\telse if (applyTo.find(" h") != std::string::npos) {\n\t\tdrawLeft = true;\n\t\tdrawRight = true;\n\t}\n\telse if (applyTo.find(" v") != std::string::npos) {\n\t\tdrawTop = true;\n\t\tdrawBottom = true;\n\t}\n\tif (applyTo.find(" no") != std::string::npos) {\n\t\tif (applyTo.find(" noM") != std::string::npos) {\n\t\t\t\/\/middle\n\t\t\tif (applyTo.find(" noMrow") != std::string::npos) {\n\t\t\t\tdrawMiddle = false;\n\t\t\t\tdrawLeft = false;\n\t\t\t\tdrawRight = false;\n\t\t\t}\n\t\t\tif (applyTo.find(" noMcol") != std::string::npos) {\n\t\t\t\tdrawMiddle = false;\n\t\t\t\tdrawTop = false;\n\t\t\t\tdrawBottom = false;\n\t\t\t}\n\t\t\tif (applyTo.find(" noMid") != std::string::npos)\n\t\t\t\tdrawMiddle = false;\n\t\t}\n\t\tif (applyTo.find(" noN") != std::string::npos) {\n\t\t\t\/\/north\n\t\t\tif (applyTo.find(" noNrow") != std::string::npos) {\n\t\t\t\tdrawTop = false;\n\t\t\t\tdrawTopLeft = false;\n\t\t\t\tdrawTopRight = false;\n\t\t\t}\n\t\t\tif (applyTo.find(" noNedge") != std::string::npos)\n\t\t\t\tdrawTop = false;\n\t\t\tif (applyTo.find(" noNW") != std::string::npos)\n\t\t\t\tdrawTopLeft = false;\n\t\t\tif (applyTo.find(" noNE") != std::string::npos)\n\t\t\t\tdrawTopRight = false;\n\t\t}\n\t\tif (applyTo.find(" noS") != std::string::npos) {\n\t\t\t\/\/south\n\t\t\tif (applyTo.find(" noSrow") != std::string::npos) {\n\t\t\t\tdrawBottom = false;\n\t\t\t\tdrawBottomLeft = false;\n\t\t\t\tdrawBottomRight = false;\n\t\t\t}\n\t\t\tif (applyTo.find(" noSedge") != std::string::npos)\n\t\t\t\tdrawBottom = false;\n\t\t\tif (applyTo.find(" noSW") != std::string::npos)\n\t\t\t\tdrawBottomLeft = false;\n\t\t\tif (applyTo.find(" noSE") != std::string::npos)\n\t\t\t\tdrawBottomRight = false;\n\t\t}\n\t\tif (applyTo.find(" noW") != std::string::npos) {\n\t\t\t\/\/west\n\t\t\tif (applyTo.find(" noWcol") != std::string::npos) {\n\t\t\t\tdrawLeft = false;\n\t\t\t\tdrawTopLeft = false;\n\t\t\t\tdrawBottomLeft = false;\n\t\t\t}\n\t\t\tif (applyTo.find(" noWedge") != std::string::npos)\n\t\t\t\tdrawLeft = false;\n\t\t}\n\t\tif (applyTo.find(" noE") != std::string::npos) {\n\t\t\t\/\/east\n\t\t\tif (applyTo.find(" noEcol") != std::string::npos) {\n\t\t\t\tdrawRight = false;\n\t\t\t\tdrawTopRight = false;\n\t\t\t\tdrawBottomRight = false;\n\t\t\t}\n\t\t\tif (applyTo.find(" noEedge") != std::string::npos)\n\t\t\t\tdrawRight = false;\n\t\t}\n\t}\n\tlockGroup(pMB);\n\t\/\/middle\n\tif (pVS->whl[0] > 0 && pVS->whl[1] > 0 && drawMiddle) {\n\t\tbuildBoxFacePlain(pMB, applyTo, pVS);\n\t}\n\tVirtualShape vs;\n\t\/\/edges\n\t\/\/vs.type.assign("cylinder");\n\tvs.sectionsR = pVS->sectionsR;\n\tif (pVS->whl[0] > 0) {\n\t\tvs.sections[2] = pVS->sections[0]; \/\/cylinder Z sections n\n\t\tvs.whl[2] = pVS->whl[0]; \/\/cylinder length Z\n\t\tvs.whl[0] = pVS->extF * 2; \/\/cylinder diameter X\n\t\tif (pVS->extU > 0 && drawTop) {\n\t\t\tvs.whl[1] = pVS->extU * 2; \/\/cylinder diameter Y\n\t\t\tlockGroup(pMB);\n\t\t\tcylinderWrap(pMB, &vs, 0, 90);\n\t\t\t\/\/rotate -90 degrees around Y and shift up\n\t\t\tmoveGroupDg(pMB, 0, -90, 0, 0, pVS->whl[1] * 0.5f, 0);\n\t\t\treleaseGroup(pMB);\n\t\t}\n\t\tif (pVS->extD > 0 && drawBottom) {\n\t\t\tvs.whl[1] = pVS->extD * 2; \/\/cylinder diameter Y\n\t\t\tlockGroup(pMB);\n\t\t\tcylinderWrap(pMB, &vs, -90, 0);\n\t\t\t\/\/rotate -90 degrees around Y and shift down\n\t\t\tmoveGroupDg(pMB, 0, -90, 0, 0, -pVS->whl[1] * 0.5f, 0);\n\t\t\treleaseGroup(pMB);\n\t\t}\n\t}\n\tif (pVS->whl[1] > 0) {\n\t\tvs.sections[2] = pVS->sections[1]; \/\/cylinder Z sections n\n\t\tvs.whl[2] = pVS->whl[1]; \/\/cylinder length Z\n\t\tvs.whl[1] = pVS->extF * 2; \/\/cylinder diameter Y\n\t\tif (pVS->extL > 0 && drawLeft) {\n\t\t\tvs.whl[0] = pVS->extL * 2; \/\/cylinder diameter X\n\t\t\tlockGroup(pMB);\n\t\t\tcylinderWrap(pMB, &vs, 90, 180);\n\t\t\t\/\/rotate 90 degrees around Y and shift left\n\t\t\tmoveGroupDg(pMB, 90, 0, 0, -pVS->whl[0] * 0.5f, 0, 0);\n\t\t\treleaseGroup(pMB);\n\t\t}\n\t\tif (pVS->extR > 0 && drawRight) {\n\t\t\tvs.whl[0] = pVS->extR * 2; \/\/cylinder diameter X\n\t\t\tlockGroup(pMB);\n\t\t\tcylinderWrap(pMB, &vs, 0, 90);\n\t\t\t\/\/rotate 90 degrees around Y and shift left\n\t\t\tmoveGroupDg(pMB, 90, 0, 0, pVS->whl[0] * 0.5f, 0, 0);\n\t\t\treleaseGroup(pMB);\n\t\t}\n\t}\n\t\/\/corners\n\t\/\/vs.type.assign("cap");\n\tvs.sectionsR = pVS->sectionsR;\n\tvs.sections[2] = pVS->sectionsR;\n\tvs.whl[2] = pVS->extF;\n\tif (pVS->extU > 0) {\n\t\t\/\/top corners\n\t\tvs.whl[1] = pVS->extU * 2;\n\t\tif (pVS->extL > 0 && drawTopLeft) {\n\t\t\tvs.whl[0] = pVS->extL * 2;\n\t\t\tlockGroup(pMB);\n\t\t\tcapWrap(pMB, &vs, 90, 180);\n\t\t\t\/\/rotate 90 degrees around Y and shift left\n\t\t\tmoveGroupDg(pMB, 0, 0, 0, -pVS->whl[0] * 0.5f, pVS->whl[1] * 0.5f, 0);\n\t\t\treleaseGroup(pMB);\n\t\t}\n\t\tif (pVS->extR > 0 && drawTopRight) {\n\t\t\tvs.whl[0] = pVS->extR * 2;\n\t\t\tlockGroup(pMB);\n\t\t\tcapWrap(pMB, &vs, 0, 90);\n\t\t\t\/\/rotate 90 degrees around Y and shift left\n\t\t\tmoveGroupDg(pMB, 0, 0, 0, pVS->whl[0] * 0.5f, pVS->whl[1] * 0.5f, 0);\n\t\t\treleaseGroup(pMB);\n\n\t\t}\n\t}\n\tif (pVS->extD > 0) {\n\t\t\/\/bottom corners\n\t\tvs.whl[1] = pVS->extD * 2;\n\t\tif (pVS->extL > 0 && drawBottomLeft) {\n\t\t\tvs.whl[0] = pVS->extL * 2;\n\t\t\tlockGroup(pMB);\n\t\t\tcapWrap(pMB, &vs, -180, -90);\n\t\t\t\/\/rotate 90 degrees around Y and shift left\n\t\t\tmoveGroupDg(pMB, 0, 0, 0, -pVS->whl[0] * 0.5f, -pVS->whl[1] * 0.5f, 0);\n\t\t\treleaseGroup(pMB);\n\t\t}\n\t\tif (pVS->extR > 0 && drawBottomRight) {\n\t\t\tvs.whl[0] = pVS->extR * 2;\n\t\t\tlockGroup(pMB);\n\t\t\tcapWrap(pMB, &vs, -90, 0);\n\t\t\t\/\/rotate 90 degrees around Y and shift left\n\t\t\tmoveGroupDg(pMB, 0, 0, 0, pVS->whl[0] * 0.5f, -pVS->whl[1] * 0.5f, 0);\n\t\t\treleaseGroup(pMB);\n\t\t}\n\t}\n\tif (pVS->extF == 0) {\n\t\tint vertsN = pMB->vertices.size();\n\t\tfor (int i = pMB->pCurrentGroup->fromVertexN; i < vertsN; i++) {\n\t\t\tVertex01* pVX = pMB->vertices.at(i);\n\t\t\t\/\/normal\n\t\t\tv3set(pVX->aNormal, 0, 0, 1);\n\t\t}\n\t}\n\treleaseGroup(pMB);\n\treturn 1;\n}\n\nint ModelBuilder::cylinderWrap(ModelBuilder* pMB, VirtualShape* pVS, float angleFrom, float angleTo) {\n\t\/\/ angleFrom\/To - in degrees\n\tlockGroup(pMB);\n\tfloat stepZ = pVS->whl[2] \/ pVS->sections[2];\n\tfloat stepDg = (angleTo - angleFrom) \/ pVS->sectionsR; \/\/in degrees\n\tfor (int nz = 0; nz <= pVS->sections[2]; nz++) {\n\t\tfloat kz = stepZ * nz - pVS->whl[2] * 0.5f;\n\t\tfor (int rpn = 0; rpn <= pVS->sectionsR; rpn++) {\n\t\t\t\/\/ rpn - radial point number\n\t\t\tfloat angleRd = (angleFrom + stepDg * rpn) * degrees2radians;\n\t\t\tfloat kx = cosf(angleRd);\n\t\t\tfloat ky = sinf(angleRd);\n\t\t\tint nSE = addVertex(pMB, kx, ky, kz, kx, ky, 0);\n\t\t\tif (nz > 0 && rpn > 0) {\n\t\t\t\tint nSW = nSE - 1;\n\t\t\t\tint nNW = nSW - pVS->sectionsR - 1;\n\t\t\t\tint nNE = nSE - pVS->sectionsR - 1;\n\t\t\t\tadd2triangles(pMB, nNE, nNW, nSE, nSW, nz + rpn);\n\t\t\t}\n\t\t}\n\t}\n\t\/\/scale to desirable diameters\n\tmat4x4 transformMatrix = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };\n\tmat4x4_scale_aniso(transformMatrix, transformMatrix, pVS->whl[0] * 0.5f, pVS->whl[1] * 0.5f, 1);\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}\n\treleaseGroup(pMB);\n\treturn 1;\n}\nint ModelBuilder::capWrap(ModelBuilder* pMB, VirtualShape* pVS, float angleFrom, float angleTo) {\n\t\/\/ angleFrom\/To - in degrees\n\tlockGroup(pMB);\n\t\/\/center point\n\tint n0 = addVertex(pMB, 0, 0, 1, 0, 0, 1);\n\tfloat stepZdg = 90.0f \/ pVS->sections[2]; \/\/in degrees\n\tfloat stepRdg = (angleTo - angleFrom) \/ pVS->sectionsR; \/\/in degrees\n\tfor (int nz = 1; nz <= pVS->sections[2]; nz++) {\n\t\tfloat angleZrd = stepZdg * nz * degrees2radians;\n\t\tfloat kz = cosf(angleZrd);\n\t\tfloat R = sinf(angleZrd);\n\t\tfor (int rpn = 0; rpn <= pVS->sectionsR; rpn++) {\n\t\t\t\/\/ rpn - radial point number\n\t\t\tfloat angleRd = (angleFrom + stepRdg * rpn) * degrees2radians;\n\t\t\tfloat kx = cosf(angleRd) * R;\n\t\t\tfloat ky = sinf(angleRd) * R;\n\t\t\tint nSE = addVertex(pMB, kx, ky, kz, kx, ky, kz);\n\t\t\tif (rpn > 0) {\n\t\t\t\tif (nz == 1) {\n\t\t\t\t\tint nSW = nSE - 1;\n\t\t\t\t\taddTriangle(pMB, n0, nSW, nSE);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tint nSW = nSE - 1;\n\t\t\t\t\tint nNW = nSW - pVS->sectionsR - 1;\n\t\t\t\t\tint nNE = nSE - pVS->sectionsR - 1;\n\t\t\t\t\tadd2triangles(pMB, nNW, nNE, nSW, nSE, nz + rpn);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\/\/scale to desirable diameters\n\tmat4x4 transformMatrix = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };\n\tmat4x4_scale_aniso(transformMatrix, transformMatrix, pVS->whl[0] * 0.5f, pVS->whl[1] * 0.5f, pVS->whl[2]);\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}\n\treleaseGroup(pMB);\n\treturn 1;\n}\nint ModelBuilder::groupApplyTexture(ModelBuilder* pMB, std::string applyTo, TexCoords* pTC, TexCoords* pTC2nm) {\n\tint vertsN = pMB->vertices.size();\n\tfor (int vN = 0; vN < vertsN; vN++) {\n\t\tVertex01* pVX = pMB->vertices.at(vN);\n\t\tif(vN < pMB->pCurrentGroup->fromVertexN)\n\t\t\tpVX->flag = -1;\n\t\telse\n\t\t\tpVX->flag = 0;\n\t}\n\tapplyTexture2flagged(&pMB->vertices, applyTo, pTC, false);\n\tapplyTexture2flagged(&pMB->vertices, applyTo, pTC2nm, true);\n\treturn 1;\n}\nint ModelBuilder::applyTexture2flagged(std::vector<Vertex01*>* pVerts, std::string applyTo, TexCoords* pTC, bool isNormalMap) {\n\tif (pTC == NULL)\n\t\treturn 0;\n\tfloat posMin[3];\n\tfloat posMax[3];\n\tfloat posRange[3];\n\tfor (int i = 0; i < 3; i++) {\n\t\tposMin[i] = 1000000;\n\t\tposMax[i] = -1000000;\n\t}\n\tint vertsN = pVerts->size();\n\tfor (int vN = 0; vN < vertsN; vN++) {\n\t\tVertex01* pVX = pVerts->at(vN);\n\t\tif (pVX->flag < 0) \/\/ignore\n\t\t\tcontinue;\n\t\tfor (int i = 0; i < 3; i++) {\n\t\t\tif (posMin[i] > pVX->aPos[i])\n\t\t\t\tposMin[i] = pVX->aPos[i];\n\t\t\tif (posMax[i] < pVX->aPos[i])\n\t\t\t\tposMax[i] = pVX->aPos[i];\n\t\t}\n\t}\n\t\/\/here we have coordinates range\n\tfor (int i = 0; i < 3; i++)\n\t\tposRange[i] = posMax[i] - posMin[i];\n\t\/\/for "front"\n\tint xRateIndex = 0;\n\tbool xRateInverse = false;\n\tint yRateIndex = 1;\n\tbool yRateInverse = true;\n\tif (applyTo.find("front") == 0)\n\t\t; \/\/do nothing\n\telse if (applyTo.find("back") == 0)\n\t\txRateInverse = true;\n\telse if (applyTo.find("left") == 0)\n\t\txRateIndex = 2;\n\telse if (applyTo.find("right") == 0) {\n\t\txRateIndex = 2;\n\t\txRateInverse = true;\n\t}\n\telse if (applyTo.find("top") == 0) {\n\t\txRateInverse = true;\n\t\tyRateIndex = 2;\n\t}\n\telse if (applyTo.find("bottom") == 0)\n\t\tyRateIndex = 2;\n\n\tfloat xRate = 0;\n\tfloat yRate = 0;\n\tfloat tuvRange[2];\n\ttuvRange[0] = pTC->tuvBottomRight[0] - pTC->tuvTopLeft[0];\n\ttuvRange[1] = pTC->tuvBottomRight[1] - pTC->tuvTopLeft[1];\n\tfor (int vN = 0; vN < vertsN; vN++) {\n\t\tVertex01* pVX = pVerts->at(vN);\n\t\tif (pVX->flag < 0) \/\/ignore\n\t\t\tcontinue;\n\t\tif (posRange[xRateIndex] == 0)\n\t\t\txRate = 0;\n\t\telse {\n\t\t\txRate = (pVX->aPos[xRateIndex] - posMin[xRateIndex]) \/ posRange[xRateIndex];\n\t\t\tif (xRateInverse)\n\t\t\t\txRate = 1.0f - xRate;\n\t\t}\n\t\tif (posRange[yRateIndex] == 0)\n\t\t\tyRate = 0;\n\t\telse {\n\t\t\tyRate = (pVX->aPos[yRateIndex] - posMin[yRateIndex]) \/ posRange[yRateIndex];\n\t\t\tif (yRateInverse)\n\t\t\t\tyRate = 1.0f - yRate;\n\t\t}\n\t\tfloat* pTuv = pVX->aTuv;\n\t\tif(isNormalMap)\n\t\t\tpTuv = pVX->aTuv2;\n\t\tpTuv[0] = pTC->tuvTopLeft[0] + tuvRange[0] * xRate;\n\t\tpTuv[1] = pTC->tuvTopLeft[1] + tuvRange[1] * yRate;\n\t}\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n
<\/p>\n\n\n\n
<\/p>\n\n\n\n