\n#pragma once\n#include "ModelBuilder.h"\n\nclass GroupTransform\n{\npublic:\n\tfloat shift[4] = { 0,0,0,0 };\n\tfloat spin[3] = { 0,0,0 }; \/\/in degrees\npublic:\n\tint executeGroupTransform(ModelBuilder* pMB) { return executeGroupTransform(pMB, this); };\n\tstatic int executeGroupTransform(ModelBuilder* pMB, GroupTransform* pGT);\n};\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
\n\n\n\n5. \u041f\u043e\u0434 modeler <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 C++ file GroupTransform.cpp<\/strong><\/p>\n\n\n\nLocation: C:\\CPP\\engine\\modeler<\/em><\/p>\n\n\n\n\u041a\u043e\u0434:<\/p>\n\n\n
\n#include "GroupTransform.h"\n\nint GroupTransform::executeGroupTransform(ModelBuilder* pMB, GroupTransform* pGT) {\n\tpMB->moveGroupDg(pMB, pGT->spin[0], pGT->spin[1], pGT->spin[2], pGT->shift[0], pGT->shift[1], pGT->shift[2]);\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
\n\n\n\n\u0412 ModelLoader<\/strong>-\u0435 – \u043d\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b:<\/p>\n\n\n\n- fillProps_gt(..)<\/em> – \u0447\u0442\u0435\u043d\u0438\u0435\/\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 GroupTrandform <\/em>info.<\/li>
- processTag_a(..)<\/em> \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u0438\u0435\u043c\u0430 \u043f\u043e\u0434-\u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a VirtualShape <\/em>\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 GroupTrandform <\/em>\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 “a”).<\/li>
- \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0442\u0430\u0433\u0430 “clone” – processTag_clone(..)<\/em><\/li><\/ul>\n\n\n\n
6. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelLoader.h<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n\n#pragma once\n#include "XMLparser.h"\n#include "ModelBuilder.h"\n#include "GroupTransform.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 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, std::string tagStr);\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\tstatic int processTag_clone(ModelLoader* pML);\n};\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
\n\n\n\n7. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelLoader.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\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::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\tif (pML->tagName.compare("\/group") == 0) {\n\t\tGroupTransform groupTransform;\n\t\tfillProps_gt(&groupTransform, pML->currentTag);\n\t\tgroupTransform.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\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::fillProps_gt(GroupTransform* pGS, std::string tagStr) {\n\t\/\/position\n\tsetFloatArray(pGS->shift, 3, "pxyz", tagStr);\n\tsetFloatValue(&pGS->shift[0], "px", tagStr);\n\tsetFloatValue(&pGS->shift[1], "py", tagStr);\n\tsetFloatValue(&pGS->shift[2], "pz", tagStr);\n\t\/\/angles\n\tsetFloatArray(pGS->spin, 3, "axyz", tagStr);\n\tsetFloatValue(&pGS->spin[0], "ax", tagStr);\n\tsetFloatValue(&pGS->spin[1], "ay", tagStr);\n\tsetFloatValue(&pGS->spin[2], "az", tagStr);\n\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\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\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\t\/\/pMB->buildFace(pMB, applyTosVector.at(aN), pMB->pCurrentVShape, &tc, &tc2nm);\n\t\tpMB->buildFace(pMB, applyTosVector.at(aN), pVS_a, &tc, &tc2nm);\n\t}\n\tdelete pVS_a;\n\t\/\/mylog("vertsN=%d\\n",pMB->vertices.size());\n\n\tGroupTransform GT_a;\n\tfillProps_gt(>_a, 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\/\/cloning\n\t\tint vertsN = pMB->vertices.size() - pMB->pLastClosedGroup->fromVertexN;\n\t\tint trianglesN = pMB->triangles.size() - pMB->pLastClosedGroup->fromTriangleN;\n\t\tpMB->lockGroup(pMB);\n\t\tfor (int i = 0; i < vertsN; i++) {\n\t\t\tint vN = pMB->pLastClosedGroup->fromVertexN + i;\n\t\t\tVertex01* pV = new Vertex01(*pMB->vertices.at(vN));\n\t\t\tpMB->vertices.push_back(pV);\n\t\t}\n\t\tfor (int i = 0; i < trianglesN; i++) {\n\t\t\tint tN = pMB->pLastClosedGroup->fromTriangleN + i;\n\t\t\tTriangle01* pT = new Triangle01(*pMB->triangles.at(tN));\n\t\t\tfor (int n = 0; n < 3; n++)\n\t\t\t\tpT->idx[n] += vertsN;\n\t\t\tpMB->triangles.push_back(pT);\n\t\t}\n\t}\n\tGroupTransform groupTransform;\n\tfillProps_gt(&groupTransform, pML->currentTag);\n\tgroupTransform.executeGroupTransform(pMB);\n\tif (pML->tagName.compare("\/clone") == 0 || pML->closedTag) {\n\t\tpMB->releaseGroup(pMB);\n\t}\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
\n\n\n\n\u0422\u0430\u0433 “clone” \u0432 ModelLoader-\u0435<\/em> \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e pLastClosedGroup<\/em> \u0432 ModelBuilder1base<\/em>.<\/p>\n\n\n\n8. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder1base<\/em>.h<\/em> \u043a\u043e\u0434 \u043d\u0430: <\/p>\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\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<\/p>\n\n\n\n
\n\n\n\n\u042d\u0442\u0430 \u043d\u043e\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f pLastClosedGroup<\/em> \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 ModelBuilder1base::releaseGroup()<\/em><\/p>\n\n\n\n9. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelBuilder1base<\/em>.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430: <\/p>\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}\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->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<\/p>\n\n\n\n
\n\n\n\n10. \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a.<\/p>\n\n\n\n
\u0414\u043e<\/strong>:<\/p>\n\n\n\n
<\/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\n
<\/p>\n\n\n\n