void ModelContainer::fillContainer(const AABSPTree<SubModel *>::Node& pNode, int &pSubModelPos, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi, Vector3& pFinalLo, Vector3& pFinalHi) { // TreeNode for the SubModel TreeNode treeNode = TreeNode(pNode.valueArray.size(), pSubModelPos); treeNode.setSplitAxis(pNode.splitAxis); treeNode.setSplitLocation(pNode.splitLocation); int currentTreeNodePos = pTreeNodePos++; Vector3 lo = Vector3(inf(),inf(),inf()); Vector3 hi = Vector3(-inf(),-inf(),-inf()); for (int i=0; i<pNode.valueArray.size(); i++) { G3D::_AABSPTree::Handle<SubModel*>* h= pNode.valueArray[i]; SubModel *m = h->value; memcpy(&getTreeNodes()[pTreeNodePos], &m->getTreeNode(0), sizeof(TreeNode) * m->getNNodes()); memcpy(&getTriangles()[pTrianglePos], &m->getTriangle(0), sizeof(TriangleBox) * m->getNTriangles()); SubModel newModel = SubModel(m->getNTriangles(), getTriangles(), pTrianglePos, m->getNNodes(), getTreeNodes(), pTreeNodePos); newModel.setReletiveBounds(m->getReletiveBounds().getLo(), m->getReletiveBounds().getHi()); newModel.setBasePosition(m->getBasePosition()); iSubModel[pSubModelPos++] = newModel; pTreeNodePos += m->getNNodes(); pTrianglePos += m->getNTriangles(); AABox box = m->getAABoxBounds(); lo = lo.min(box.low()); hi = hi.max(box.high()); pFinalLo = pFinalLo.min(lo); pFinalHi = pFinalHi.max(hi); } /* if(pNode.valueArray.size() == 0) { int xxx = 0; // just for the breakpoint } */ // get absolute bounds if(pNode.child[0] != 0) { treeNode.setChildPos(0, pTreeNodePos); fillContainer(*pNode.child[0], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi); } if(pNode.child[1] != 0) { treeNode.setChildPos(1, pTreeNodePos); fillContainer(*pNode.child[1], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi); } pLo = pLo.min(lo); pHi = pHi.max(hi); treeNode.setBounds(lo,hi); setTreeNode(treeNode, currentTreeNodePos); }
//================================================================= bool TileAssembler::readRawFile(std::string& pModelFilename, ModelPosition& pModelPosition, AABSPTree<SubModel *> *pMainTree) { bool result = false; std::string filename = iSrcDir; if(filename.length() >0) filename.append("/"); filename.append(pModelFilename); FILE *rf = fopen(filename.c_str(), "rb"); if(!rf) { // depending on the extractor version, the data could be located in the root dir std::string baseModelFilename = pModelFilename.substr((pModelFilename.find_first_of("/")+1),pModelFilename.length()); filename = iSrcDir; if(filename.length() >0) filename.append("/"); filename.append(baseModelFilename); rf = fopen(filename.c_str(), "rb"); } char ident[8]; int trianglecount =0; #ifdef _ASSEMBLER_DEBUG int startgroup = 0; //2; int endgroup = INT_MAX; //2; fprintf(::g_df,"-------------------------------------------------\n"); fprintf(::g_df,"%s\n", pModelFilename.c_str()); fprintf(::g_df,"-------------------------------------------------\n"); #else int startgroup = 0; int endgroup = INT_MAX; #endif if(rf) { if(fread(&ident, 8, 1, rf) != 1) { fclose(rf); return(false); } if(strcmp(ident, "VMAP001") == 0) { // OK, do nothing } else if(strcmp(ident, "VMAP002") == 0) { // we have to read one int. This is needed during the export and we have to skip it here int tempNVectors; if(fread(&tempNVectors, sizeof(int), 1, rf) != 1) { fclose(rf); return(false); } } else { // wrong version fclose(rf); return(false); } uint32 groups; char blockId[5]; blockId[4] = 0; int blocksize; if(fread(&groups, sizeof(uint32), 1, rf) != 1) { fclose(rf); return(false); } for(int g=0;g<(int)groups;g++) { // group MUST NOT have more then 65536 indexes !! Array will have a problem with that !! (strange ...) Array<int> tempIndexArray; Array<Vector3> tempVertexArray; AABSPTree<Triangle> *gtree = new AABSPTree<Triangle>(); uint32 flags; uint32 isindoor = 0; uint32 branches; if(fread(&flags, sizeof(uint32), 1, rf) != 1) { fclose(rf); return(false); } if(flags & 1) { if(fread(&isindoor, sizeof(uint32), 1, rf) != 1) { fclose(rf); return(false); } } if(fread(&blockId, 4, 1, rf) != 1) { fclose(rf); return(false); } if(strcmp(blockId, "GRP ") != 0) { if(fread(&blockId, 4, 1, rf) != 1) { fclose(rf); return(false); } } if(strcmp(blockId, "GRP ") != 0) { printf("BUG: (%s)\n",blockId); fclose(rf); return(false); } if(fread(&blocksize, sizeof(int), 1, rf) != 1) { fclose(rf); return(false); } if(fread(&branches, sizeof(uint32), 1, rf) != 1) { fclose(rf); return(false); } for(int b=0;b<(int)branches; b++) { uint32 indexes; // indexes for each branch (not used jet) if(fread(&indexes, sizeof(uint32), 1, rf) != 1) { fclose(rf); return(false); } } // ---- indexes if(fread(&blockId, 4, 1, rf) != 1) { fclose(rf); return(false); } if(strcmp(blockId, "INDX") != 0) { fclose(rf); return(false); } if(fread(&blocksize, sizeof(int), 1, rf) != 1) { fclose(rf); return(false); } unsigned int nindexes; if(fread(&nindexes, sizeof(uint32), 1, rf) != 1) { fclose(rf); return(false); } if(nindexes >0) { unsigned short *indexarray = new unsigned short[nindexes*sizeof(unsigned short)]; if(fread(indexarray, sizeof(unsigned short), nindexes, rf) != nindexes) { fclose(rf); return(false); } for(int i=0;i<(int)nindexes; i++) { unsigned short val = indexarray[i]; tempIndexArray.append(val); } delete indexarray; } // ---- vectors if(fread(&blockId, 4, 1, rf) != 1) {fclose(rf); return(false); } if(strcmp(blockId, "VERT") != 0) { fclose(rf); return(false); } if(fread(&blocksize, sizeof(int), 1, rf) != 1) { fclose(rf); return(false); } unsigned int nvectors; if(fread(&nvectors, sizeof(int), 1, rf) != 1) { fclose(rf); return(false); } float *vectorarray = 0; if(nvectors >0) { vectorarray = new float[nvectors*sizeof(float)*3]; if(fread(vectorarray, sizeof(float)*3, nvectors, rf) != nvectors) { fclose(rf); return(false); } } // ----- liquit if(flags & 0x00001000) { // we have liquit -> not handled yet ... skip if(fread(&blockId, 4, 1, rf) != 1) { fclose(rf); return(false); } if(strcmp(blockId, "LIQU") != 0) { fclose(rf); return(false); } if(fread(&blocksize, sizeof(int), 1, rf) != 1) { fclose(rf); return(false); } fseek(rf, blocksize, SEEK_CUR); } for(unsigned int i=0, indexNo=0; indexNo<nvectors; indexNo++) { Vector3 v = Vector3(vectorarray[i+2], vectorarray[i+1], vectorarray[i+0]); i+=3; v = pModelPosition.transform(v); float swapy = v.y; v.y = v.x; v.x = swapy; tempVertexArray.append(v); } // ---- calculate triangles int rest = nindexes%3; if(rest != 0) { nindexes -= rest; } for(unsigned int i=0;i<(nindexes);) { Triangle t = Triangle(tempVertexArray[tempIndexArray[i+2]], tempVertexArray[tempIndexArray[i+1]], tempVertexArray[tempIndexArray[i+0]] ); i+=3; ++trianglecount; if(g>= startgroup && g <= endgroup) { gtree->insert(t); } } if(vectorarray != 0) { delete vectorarray; } if(gtree->size() >0) { gtree->balance(); SubModel *sm = new SubModel(gtree); sm->setIndoorFlag( isindoor ); #ifdef _ASSEMBLER_DEBUG if(::g_df) fprintf(::g_df,"group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); if(sm->getNTriangles() != gtree->memberTable.size()) { if(::g_df) fprintf(::g_df,"ERROR !!!! group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); } #endif sm->setBasePosition(pModelPosition.iPos); pMainTree->insert(sm); } delete gtree; } fclose(rf); result = true; } return(result); }
//================================================================= bool TileAssembler::readRawFile(std::string& pModelFilename, ModelPosition& pModelPosition, AABSPTree<SubModel *> *pMainTree) { std::string filename = iSrcDir; if (filename.length() >0) filename.append("/"); filename.append(pModelFilename); FILE *rf = fopen(filename.c_str(), "rb"); if (!rf) { // depending on the extractor version, the data could be located in the root dir std::string baseModelFilename = pModelFilename.substr((pModelFilename.find_first_of("/")+1),pModelFilename.length()); filename = iSrcDir; if (filename.length() >0) filename.append("/"); filename.append(baseModelFilename); rf = fopen(filename.c_str(), "rb"); } if (!rf) { printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str()); printf("... or form: %s",filename.c_str() ); return false; } char ident[8]; int trianglecount =0; #ifdef _ASSEMBLER_DEBUG int startgroup = 0; //2; int endgroup = INT_MAX; //2; fprintf(::g_df,"-------------------------------------------------\n"); fprintf(::g_df,"%s\n", pModelFilename.c_str()); fprintf(::g_df,"-------------------------------------------------\n"); #else int startgroup = 0; int endgroup = INT_MAX; #endif // temporary use defines to simplify read/check code (close file and return at fail) #define READ_OR_RETURN(V,S) if (fread((V), (S), 1, rf) != 1) { \ fclose(rf); return(false); } #define CMP_OR_RETURN(V,S) if (strcmp((V),(S)) != 0) { \ fclose(rf); return(false); } READ_OR_RETURN(&ident, 8); if (strcmp(ident, "VMAP001") == 0) { // OK, do nothing } else if (strcmp(ident, "VMAP002") == 0) { // we have to read one int. This is needed during the export and we have to skip it here int tempNVectors; READ_OR_RETURN(&tempNVectors, sizeof(int)); } else { // wrong version fclose(rf); return(false); } G3D::uint32 groups; char blockId[5]; blockId[4] = 0; int blocksize; READ_OR_RETURN(&groups, sizeof(G3D::uint32)); for (int g=0;g<(int)groups;g++) { // group MUST NOT have more then 65536 indexes !! Array will have a problem with that !! (strange ...) Array<int> tempIndexArray; Array<Vector3> tempVertexArray; AABSPTree<Triangle> *gtree = new AABSPTree<Triangle>(); // add free gtree at fail #undef READ_OR_RETURN #undef CMP_OR_RETURN #define READ_OR_RETURN(V,S) if (fread((V), (S), 1, rf) != 1) { \ fclose(rf); delete gtree; return(false); } #define CMP_OR_RETURN(V,S) if (strcmp((V),(S)) != 0) { \ fclose(rf); delete gtree; return(false); } G3D::uint32 flags; READ_OR_RETURN(&flags, sizeof(G3D::uint32)); G3D::uint32 branches; READ_OR_RETURN(&blockId, 4); CMP_OR_RETURN(blockId, "GRP "); READ_OR_RETURN(&blocksize, sizeof(int)); READ_OR_RETURN(&branches, sizeof(G3D::uint32)); for (int b=0;b<(int)branches; b++) { G3D::uint32 indexes; // indexes for each branch (not used jet) READ_OR_RETURN(&indexes, sizeof(G3D::uint32)); } // ---- indexes READ_OR_RETURN(&blockId, 4); CMP_OR_RETURN(blockId, "INDX"); READ_OR_RETURN(&blocksize, sizeof(int)); unsigned int nindexes; READ_OR_RETURN(&nindexes, sizeof(G3D::uint32)); if (nindexes >0) { unsigned short *indexarray = new unsigned short[nindexes*sizeof(unsigned short)]; READ_OR_RETURN(indexarray, nindexes*sizeof(unsigned short)); for (int i=0;i<(int)nindexes; i++) { unsigned short val = indexarray[i]; tempIndexArray.append(val); } delete[] indexarray; } // ---- vectors READ_OR_RETURN(&blockId, 4); CMP_OR_RETURN(blockId, "VERT"); READ_OR_RETURN(&blocksize, sizeof(int)); unsigned int nvectors; READ_OR_RETURN(&nvectors, sizeof(int)); float *vectorarray = 0; // add vectorarray free #undef READ_OR_RETURN #undef CMP_OR_RETURN #define READ_OR_RETURN(V,S) if (fread((V), (S), 1, rf) != 1) { \ fclose(rf); delete gtree; delete[] vectorarray; return(false); } #define CMP_OR_RETURN(V,S) if (strcmp((V),(S)) != 0) { \ fclose(rf); delete gtree; delete[] vectorarray; return(false); } if (nvectors >0) { vectorarray = new float[nvectors*sizeof(float)*3]; READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3); } // ----- liquit if (flags & 1) { // we have liquit -> not handled yet ... skip READ_OR_RETURN(&blockId, 4); CMP_OR_RETURN(blockId, "LIQU"); READ_OR_RETURN(&blocksize, sizeof(int)); fseek(rf, blocksize, SEEK_CUR); } for (unsigned int i=0, indexNo=0; indexNo<nvectors; indexNo++) { Vector3 v = Vector3(vectorarray[i+2], vectorarray[i+1], vectorarray[i+0]); i+=3; v = pModelPosition.transform(v); float swapy = v.y; v.y = v.x; v.x = swapy; tempVertexArray.append(v); } // ---- calculate triangles int rest = nindexes%3; if (rest != 0) { nindexes -= rest; } for (unsigned int i=0;i<(nindexes);) { Triangle t = Triangle(tempVertexArray[tempIndexArray[i+2]], tempVertexArray[tempIndexArray[i+1]], tempVertexArray[tempIndexArray[i+0]] ); i+=3; ++trianglecount; if (g>= startgroup && g <= endgroup) { gtree->insert(t); } } // drop of temporary use defines #undef READ_OR_RETURN #undef CMP_OR_RETURN if (vectorarray != 0) { delete vectorarray; } if (gtree->size() >0) { gtree->balance(); SubModel *sm = new SubModel(gtree); #ifdef _ASSEMBLER_DEBUG if (::g_df) fprintf(::g_df,"group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); if (sm->getNTriangles() != gtree->memberTable.size()) { if (::g_df) fprintf(::g_df,"ERROR !!!! group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); } #endif sm->setBasePosition(pModelPosition.iPos); pMainTree->insert(sm); } delete gtree; } fclose(rf); return true; }