bool CModelExporter::ExportNode( IGameNode* pNode ) { IGameMesh* pMesh = (IGameMesh*)pNode->GetIGameObject(); IGameMaterial* pRootMat = pNode->GetNodeMaterial(); pMesh->SetUseWeightedNormals(); pMesh->InitializeData(); int uFaceCount = pMesh->GetNumberOfFaces(); for(int i = 0; i < uFaceCount; ++i) { FaceEx* pFace = pMesh->GetFace(i); for(int j = 0; j < 3; ++j) { DWORD mapIndex[3]; Point3 ptUV; int indexUV = pFace->texCoord[j]; IGameTextureMap* pMap = GetTextureMap(pRootMat, ID_DI); int nChannel = pMap->GetMapChannel(); if(pMesh->GetMapFaceIndex(nChannel, pFace->meshFaceIndex, mapIndex)) ptUV = pMesh->GetMapVertex(nChannel, mapIndex[j]); else ptUV = pMesh->GetMapVertex(nChannel, indexUV); int indexPos = pFace->vert[j]; Point3 pos = pMesh->GetVertex(indexPos); } } return true; }
void Unreal3DExport::GetAnim() { // Export vertex animation int lastvert = 0; FMeshVert nullvert = FMeshVert(); Points.SetCount(VertsPerFrame*FrameCount,TRUE); for( int t=0; t<FrameCount; ++t ) { // Progress CheckCancel(); ProgressMsg.printf(GetString(IDS_INFO_ANIM),t+1,FrameCount); pInt->ProgressUpdate(Progress+((float)t/FrameCount*U3D_PROGRESS_ANIM), FALSE, ProgressMsg.data()); // Set frame int frameverts = 0; int curframe = FrameStart + t; pScene->SetStaticFrame(curframe); // Write mesh verts for( int n=0; n<Nodes.Count(); ++n ) { CheckCancel(); IGameMesh * mesh = (IGameMesh*)Nodes[n]->GetIGameObject(); if( mesh->InitializeData() ) { int vertcount = mesh->GetNumberOfVerts(); for( int i=0; i<vertcount; ++i ) { Point3 p; if( mesh->GetVertex(i,p) ) { Points[lastvert++] = p; } } frameverts += vertcount; } Nodes[n]->ReleaseIGameObject(); } // Check number of verts in this frame if( frameverts != VertsPerFrame ) { ProgressMsg.printf(GetString(IDS_ERR_NOVERTS),curframe,frameverts,VertsPerFrame); throw MAXException(ProgressMsg.data()); } } Progress += U3D_PROGRESS_ANIM; }
Scene3DMesh* SGMExporter::ConvertMesh(IGameNode* meshNode) { std::string meshNodeName = StringUtils::ToNarrow(meshNode->GetName()); Log::LogT("exporting node '%s'", meshNodeName.c_str()); IGameMesh *gMesh = (IGameMesh*)meshNode ->GetIGameObject(); assert(gMesh); if (!gMesh ->InitializeData()) { Log::LogT("error: couldnt initialize data, skipping node"); return NULL; } if (!gMesh->IsObjectSkinned()) { Log::LogT("Mesh '%s' is not skinned", meshNodeName.c_str()); meshNode->ReleaseIGameObject(); return NULL; } else Log::LogT("Mesh '%s' is skinned", meshNodeName.c_str()); Scene3DMesh *mesh = new Scene3DMesh(); mesh->id = meshNode->GetNodeID(); mesh->name = StringUtils::ToNarrow(meshNode->GetName()); CollectProperties(mesh, gMesh); IGameMaterial *mat = meshNode ->GetNodeMaterial(); if (mat != NULL) mesh->materialName = StringUtils::ToNarrow(mat->GetMaterialName()); IGameSkin* skin = gMesh->GetIGameSkin(); for (int i = 0; i < skin->GetTotalSkinBoneCount(); i++) mesh->bonesIds.push_back(skin->GetIGameBone(i)->GetNodeID()); for (int i = 0; i < gMesh ->GetNumberOfFaces(); i++) ExtractVertices(skin, gMesh ->GetFace(i), gMesh, mesh->vertices); Log::LogT("Min bones = %d, max bones = %d", dbgMinBonesCount, dbgMaxBonesCount); meshNode ->ReleaseIGameObject(); return mesh; }
void TrianExporter::ExportNodeInfo( IGameNode * node ) { //If the node is a group owner, do nothing with it. if( !node->IsGroupOwner() ) { //Get the game object. IGameObject * obj = node->GetIGameObject(); //We will only dump the info if it is a IGAME_MESH. if( obj->GetIGameType() == IGameObject::IGAME_MESH ) { //Get the Mesh. IGameMesh * gm = ( IGameMesh * )obj; //If initialization works, dump the mesh. if( gm->InitializeData() ) DumpMesh( gm ); } } }
void CModelExporter::ExportMesh( IGameNode* pNode ) { IGameMesh* pMesh = (IGameMesh*)pNode->GetIGameObject(); pMesh->SetUseWeightedNormals(); pMesh->InitializeData(); pMesh->InitializeBinormalData(); IGameMaterial* pRootMat = pNode->GetNodeMaterial(); if(pRootMat != NULL) { size_t uMatCnt = 0; GetMaterialCnt(pRootMat, uMatCnt); m_serializer << uMatCnt; for(size_t x = 0; x < uMatCnt; x++) { size_t index = x; int nChildID; IGameMaterial* pParentMat; IGameMaterial* pMat = GetMaterial(index, pRootMat, NULL, -1, &pParentMat, &nChildID); int nMatID = 0; if(pParentMat != NULL) { nMatID = pParentMat->GetMaterialID(nChildID); BEATS_ASSERT(pParentMat->GetSubMaterial(nChildID) == pMat); } if(pMat != NULL) { ExportMeshMaterial(pNode, pMesh, pMat, nMatID, pRootMat->IsMultiType()); ExportMeshVertex(pNode, pMesh,pMat,nMatID,pRootMat->IsMultiType()); } } } }
int maxProject2::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options) { //TODO: Implement the actual file Export here and // return TRUE If the file is exported properly AllocConsole(); _cprintf( "Export Begin\n" );//¼ÇµÃ#include <conio.h> IGameConversionManager * cm = GetConversionManager(); cm->SetCoordSystem( IGameConversionManager::IGAME_D3D ); IGameScene* pSce=GetIGameInterface(); pSce->InitialiseIGame(false); pSce->SetStaticFrame(0); int num=pSce->GetTopLevelNodeCount(); // _cprintf("node count %d \n",num); // _cprintf("%s \n",name); TSTR outBuf; int matCount = pSce->GetRootMaterialCount(); // _cprintf("MaterialCount count %d \n",matCount); FILE* file=freopen(name, "w", stdout); if(!file) { return FALSE; } /*cout<<"MatreialRootList Num: "<<matCount<<endl; for(int j =0;j<matCount;j++){ IGameMaterial* rootmat=pSce->GetRootMaterial(j); int num=rootmat->GetSubMaterialCount(); TCHAR* name= rootmat->GetMaterialName(); cout<<"\tMatrial mutiType :"<<rootmat->IsMultiType()<<endl; cout<<"\ttMatreialRoot name : "<<name<<endl; cout<<"\t\tMatreialRoot #"<<j<<" ----SubMatNum : "<<num<<endl; for(int i=0;i<num;i++){ IGameMaterial* submat=rootmat->GetSubMaterial(i); cout<<"\t\tMatrial mutiType"<<submat->IsMultiType()<<endl; cout<<"\t\tSubMatName : "<<submat->GetMaterialName()<<endl; cout<<"\t\tSubMatSubNum : "<<submat->GetSubMaterialCount()<<endl; } }*/ int nodecount=pSce->GetTopLevelNodeCount(); int frame=pSce->GetSceneStartTime(); /* cout<<pSce->GetSceneStartTime()<<endl; cout<<pSce->GetSceneEndTime()<<endl; cout<<GetFrameRate()<<endl;*/ // cout<<"top level node count:"<<nodecount<<endl; for(int i=0;i<nodecount;i++) { IGameNode* topnode=pSce->GetTopLevelNode(i); IGameObject* obj=topnode->GetIGameObject(); // cout<<"\tnode #:"<<i<<endl; if(obj->GetIGameType()==IGameObject::IGAME_BONE) { /* cout<<"\t\t bone"<<endl; IGameSupportObject * hO = (IGameSupportObject*)obj; IGameMesh * hm = hO->GetMeshObject(); if(hm->InitializeData()) { int num = hm->GetNumberOfVerts(); cout<<"\t\t number of vertex : "<<num<<endl; cout<<"\t\t number of texcoord : "<<hm->GetNumberOfTexVerts()<<endl; cout<<"\t\t number of normals : "<<hm->GetNumberOfNormals()<<endl; } if(obj->GetIGameSkin()){ cout<<"\t\tHAS SKIN"<<endl; } */ IGameControl* con=topnode->GetIGameControl(); IGameKeyTab keys; con->get con->GetFullSampledKeys(keys,GetFrameRate(),IGAME_ROT); int num=keys.Count(); _cprintf( "keys count %d \n",keys.Count());//¼ÇµÃ#include <conio.h> // if(num>1) // num=1; for(int i=0;i<num;i++){ Matrix3 t=keys[i].sampleKey.gval.ExtractMatrix3(); _cprintf("\tkey frame time : %d\n",keys[i].t); _cprintf("\tkey frame pos : %d\n",keys[i].t/pSce->GetSceneTicks()); AffineParts ap; float rotAngle; Point3 rotAxis; float scaleAxAngle; Point3 scaleAxis; decomp_affine(t, &ap); // Quaternions are dumped as angle axis. AngAxisFromQ(ap.q, &rotAngle, rotAxis); AngAxisFromQ(ap.u, &scaleAxAngle, scaleAxis); /*_cprintf("\ttrans%f %f %f\n",ap.t.x,ap.t.y,ap.t.z); _cprintf("\trot%f %f %f %f\n",rotAxis.x, rotAxis.y, rotAxis.z, rotAngle); _cprintf("%f %f %f %f %f %f %f\n", ap.k.x, ap.k.y, ap.k.z, scaleAxis.x,scaleAxis.y,scaleAxis.z, scaleAxAngle);*/ } }else if(obj->GetIGameType()==IGameObject::IGAME_MESH){ // cout<<"\t\t mesh"<<endl; IGameMesh * hm = (IGameMesh*)obj; IGameSkin* skin=obj->GetIGameSkin(); /* if(skin){ cout<<"\t\tHAS SKIN"<<endl; if(skin->GetSkinType()== IGameSkin::IGAME_PHYSIQUE) cout<<"\t\t\tPhysique"<<endl; else cout<<"\t\t\tmaxskin"<<endl; int bn=skin->GetNumberOfBones(0); cout<<"\t\t\t number of bones for 0 :"<<skin->GetNumberOfBones(0)<<endl; for(int i=0;i<bn;i++){ cout<<"\t\t\t"<<skin->GetBone(0,i)->GetName()<<endl; cout<<"\t\t\t"<<skin->GetWeight(0,i)<<endl; } cout<<"\t\t\t total number of bones :"<<skin->GetTotalBoneCount()<<endl; }*/ if(hm->InitializeData()) { cout<<"m"<<endl; int num = hm->GetNumberOfVerts(); /* cout<<"\t\t number of vertex : "<<num<<endl; cout<<"\t\t number of texcoord : "<<hm->GetNumberOfTexVerts()<<endl; cout<<"\t\t number of normals : "<<hm->GetNumberOfNormals()<<endl;*/ for(int iv=0;iv<num;iv++){ Point3 v=hm->GetVertex(iv); cout<<"v "<<v.x<<" "<<v.y<<" "<<v.z<<endl; if(skin) { int bonenum=skin->GetNumberOfBones(iv); for(int bi=0;bi<bonenum;bi++) { INode* bone=skin->GetBone(iv,bi); int boneid=skin->GetBoneID(iv,bi); bone->GetNodeTM(0); cout<<"\t bone ID : "<<boneid<<" bone weight : "<<skin->GetWeight(iv,bi)<<endl; } } } cout<<"mi"<<endl; int tn=hm->GetNumberOfFaces(); for(int tv=0;tv<tn;tv++){ FaceEx* f=hm->GetFace(tv); cout<<"i "<<f->vert[0]<<" "<<f->vert[1]<<" "<<f->vert[2]<<endl; } } }else{ // cout<<"\t\t else"<<endl; } } /*if(!suppressPrompts) DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PANEL), GetActiveWindow(), maxProject2OptionsDlgProc, (LPARAM)this);*/ fclose(file); return TRUE; }
bool ExporterF3D::ExportMesh(IGameNode* node, CMesh* mesh) { IGameMesh* gameMesh = (IGameMesh*)node->GetIGameObject(); if (!gameMesh->InitializeData() || !gameMesh->IsRenderable()) { LOG_WARNING("Skipping %s - The object is not renderable", TCHARToString((node->GetName())).c_str()); return true; } /*gameMesh->SetCreateOptimizedNormalList(); gameMesh->InitializeBinormalData();*/ Box3 bbox; gameMesh->GetBoundingBox(bbox); s32 numVerts = gameMesh->GetNumberOfVerts(); s32 numNormals = gameMesh->GetNumberOfNormals(); s32 numBinormals = gameMesh->GetNumberOfBinormals(); s32 numTangents = gameMesh->GetNumberOfTangents(); s32 numTexVerts = gameMesh->GetNumberOfTexVerts(); s32 numColorVerts = gameMesh->GetNumberOfColorVerts(); s32 numAlphaVerts = gameMesh->GetNumberOfAlphaVerts(); LOG_INFO("Verts : %d", numVerts); LOG_INFO("Normals : %d", numNormals); LOG_INFO("Binormals : %d", numBinormals); LOG_INFO("Tangents : %d", numTangents); LOG_INFO("TexVerts : %d", numTexVerts); LOG_INFO("ColorVerts : %d", numColorVerts); LOG_INFO("AlphaVerts : %d", numAlphaVerts); Tab<s32> materialList = gameMesh->GetActiveMatIDs(); s32 materialCount = materialList.Count(); LOG_INFO("MaterialCount : %d", materialCount); MaterialPtr& material = const_cast<MaterialPtr&>(mesh->getMaterial()); GeometryPtr& geomerty = const_cast<GeometryPtr&>(mesh->getGeometry()); geomerty = std::make_shared<CGeometryNull>(nullptr); for (u32 i = 0; i < materialCount; ++i) { s32 matID = materialList[i]; Tab<FaceEx*> faceList = gameMesh->GetFacesFromMatID(matID); s32 numFaces = faceList.Count(); LOG_INFO("numFaces : %d", numFaces); STileUV tile; IGameMaterial* sourceMaterial = gameMesh->GetMaterialFromFace(faceList[0]); if (ExporterF3D::ExportMaterial(sourceMaterial, material, tile)) { for (u32 j = 0; j < numFaces; ++j) { FaceEx* sourceFace = faceList[j]; for (u32 k = 0; k < 3; ++k) { s32 crrIndex = ExporterF3D::findVertex(geomerty, gameMesh->GetVertex(sourceFace->vert[k], m_settings->isExportObjectSpace())); if (m_settings->isExportIndices()) { LOG_DEBUG("add Index : %d", sourceFace->vert[k]); geomerty->addIndex((crrIndex >= 0) ? crrIndex : geomerty->getData().verticesSize()); } if (!m_settings->isExportIndices() || crrIndex < 0) { Point3 vertex = gameMesh->GetVertex(sourceFace->vert[k], m_settings->isExportObjectSpace()); LOG_DEBUG("add Vertex : (%f, %f, %f)", vertex.x, vertex.y, vertex.z); geomerty->addVertex(convertPointToVector3(vertex)); if (m_settings->isExportNormals()) { Point3 normal = gameMesh->GetNormal(sourceFace->norm[k], m_settings->isExportObjectSpace()).Normalize(); LOG_DEBUG("add Normal : (%f, %f, %f)", normal.x, normal.y, normal.z); geomerty->addNormal(convertPointToVector3(normal)); } if (m_settings->isExportBinormals()) { s32 binormalTangentIndex = gameMesh->GetFaceVertexTangentBinormal(j, k); Point3 binormal = gameMesh->GetBinormal(binormalTangentIndex).Normalize(); LOG_DEBUG("add Binormal : (%f, %f, %f)", binormal.x, binormal.y, binormal.z); geomerty->addBinormal(convertPointToVector3(binormal)); } if (m_settings->isExportTangents()) { s32 binormalTangentIndex = gameMesh->GetFaceVertexTangentBinormal(j, k); Point3 tangent = gameMesh->GetTangent(binormalTangentIndex).Normalize(); LOG_DEBUG("add Tangent : (%f, %f, %f)", tangent.x, tangent.y, tangent.z); geomerty->addTangent(convertPointToVector3(tangent)); } if (m_settings->isExportColors()) { Point3 color = gameMesh->GetColorVertex(sourceFace->color[k]); core::Vector3D col = convertPointToVector3(color); col.x = core::abs(col.x); col.y = core::abs(col.y); col.z = core::abs(col.z); LOG_DEBUG("add Color : (%f, %f, %f)", col.x, col.y, col.z); geomerty->addColor(col); } if (m_settings->isExportTexCoords()) { u32 layer = 0; Point2 texCoord = gameMesh->GetTexVertex(sourceFace->texCoord[k]); texCoord.x *= tile._u; texCoord.y *= tile._v; //TODO: texcoord layers LOG_DEBUG("add TexCoord : (%f, %f)", texCoord.x, texCoord.y); geomerty->addTexCoord(layer, convertPointToVector2(texCoord)); } } } } } } return true; }
//bool MeshXMLExporter::streamSubmesh(std::ostream &of, IGameNode *node, std::string &mtlName) { bool MeshXMLExporter::streamSubmesh(std::ostream &of, IGameObject *obj, std::string &mtlName) { //IGameObject* obj = node->GetIGameObject(); if (obj->GetIGameType() != IGameMesh::IGAME_MESH) return false; // InitializeData() is important -- it performs all of the WSM/time eval for us; no face data without it // obj->InitializeData(); IGameMesh* mesh = (IGameMesh*) obj; int vertCount = mesh->GetNumberOfVerts(); int faceCount = mesh->GetNumberOfFaces(); Tab<int> matIds = mesh->GetActiveMatIDs(); Tab<DWORD> smGrpIds = mesh->GetActiveSmgrps(); Tab<int> texMaps = mesh->GetActiveMapChannelNum(); of << "\t\t<submesh "; if (mtlName.length() > 0) of << "material=\"" << mtlName << "\" "; of << "usesharedvertices=\"false\" use32bitindexes=\""; of << (vertCount > 65535); of << "\">" << std::endl; // *************** Export Face List *************** of << "\t\t\t<faces count=\"" << faceCount << "\">" << std::endl; //std::vector<UVVert // iterate the face list, putting vertices in the list for this submesh VertexList vertexList; for (int i=0; i<faceCount; i++) { of << "\t\t\t\t<face"; FaceEx* face = mesh->GetFace(i); // do this for each vertex on the face for (int vi=0; vi<3; vi++) { Point3 p = mesh->GetVertex(face->vert[vi]); Vertex v(p.x, p.y, p.z); if (m_config.getExportVertexColours()) { Point3 c = mesh->GetColorVertex(face->vert[vi]); float a = mesh->GetAlphaVertex(face->vert[vi]); v.setColour(c.x, c.y, c.z, a); } Point3 n = mesh->GetNormal(face, vi); v.setNormal(n.x, n.y, n.z); // get each set of texcoords for this vertex for (int ch=0; ch < texMaps.Count(); ch++) { Point3 tv; DWORD indices[3]; if (mesh->GetMapFaceIndex(texMaps[ch], i, indices)) tv = mesh->GetMapVertex(texMaps[ch], indices[vi]); else tv = mesh->GetMapVertex(texMaps[ch], face->vert[vi]); v.addTexCoord(texMaps[ch], tv.x, tv.y, tv.z); } int actualVertexIndex = vertexList.add(v); of << " v" << vi + 1 << "=\"" << actualVertexIndex << "\""; } of << " />" << std::endl; } of << "\t\t\t</faces>" << std::endl; // *************** End Export Face List *************** // *************** Export Geometry *************** of << "\t\t\t<geometry vertexcount=\"" << vertexList.size() << "\">" << std::endl; // *************** Export Vertex Buffer *************** bool exportNormals = true; of << std::boolalpha; of << "\t\t\t\t<vertexbuffer positions=\"true\" normals=\"" << exportNormals << "\" colours_diffuse=\"" << m_config.getExportVertexColours() << "\" texture_coords=\"" << texMaps.Count() << "\""; for (int i=0; i<texMaps.Count(); i++) of << " texture_coords_dimensions_" << i << "=\"2\""; of << ">" << std::endl; int numVerts = vertexList.size(); for (int i=0; i < numVerts; i++) { const Vertex& v = vertexList.front(); of << "\t\t\t\t\t<vertex>" << std::endl; of << std::showpoint; const Ogre::Vector3& p = v.getPosition(); float x = p.x; float y = p.y; float z = p.z; of << "\t\t\t\t\t\t<position x=\"" << x << "\" y=\"" << y << "\" z=\"" << z << "\" />" << std::endl; if (m_config.getExportVertexColours()) { float r = v.getColour().r; float g = v.getColour().g; float b = v.getColour().b; of << "\t\t\t\t\t\t<colour_diffuse value=\"\t" << r << "\t" << g << "\t" << b << "\" />" << std::endl; } if (exportNormals) { const Ogre::Vector3& n = v.getNormal(); float x = n.x; float y = n.y; float z = n.z; of << "\t\t\t\t\t\t<normal x=\"" << x << "\" y=\"" << y << "\" z=\"" << z << "\" />" << std::endl; } // output the tex coords for each map used for (int ti=0; ti<texMaps.Count(); ti++) { int texMap = texMaps[ti]; const Ogre::Vector3& uvw = v.getUVW(texMap); switch (m_config.getTexCoord2D()) { case OgreMax::UV: of << "\t\t\t\t\t\t<texcoord u=\"" << uvw.x << "\" v=\"" << (1.0 - uvw.y) << "\" />" << std::endl; break; case OgreMax::VW: of << "\t\t\t\t\t\t<texcoord v=\"" << uvw.y << "\" w=\"" << (1.0 - uvw.z) << "\" />" << std::endl; break; case OgreMax::WU: of << "\t\t\t\t\t\t<texcoord w=\"" << uvw.z << "\" u=\"" << (1.0 - uvw.x) << "\" />" << std::endl; break; } } of << std::noshowpoint; of << "\t\t\t\t\t</vertex>" << std::endl; vertexList.pop(); } of << "\t\t\t\t</vertexbuffer>" << std::endl; // *************** End Export Vertex Buffer *************** of << "\t\t\t</geometry>" << std::endl; // *************** End Export Geometry *********** of << "\t\t</submesh>" << std::endl; // this skin extraction code based on an article found here: // http://www.cfxweb.net/modules.php?name=News&file=article&sid=1029 /* Object *oRef = node->GetObjectRef(); if (oRef->SuperClassID() == GEN_DERIVOB_CLASS_ID) { IDerivedObject *dObj = (IDerivedObject *)oRef; Modifier *oMod = dObj->GetModifier(0); if (oMod->ClassID() == SKIN_CLASSID) { // flag the export of a skeleton link element m_createSkeletonLink = true; // stream the boneassignments element streamBoneAssignments(of, oMod, node); } } of << "\t\t</submesh>" << std::endl; if (obj != tri) delete tri; */ // node->ReleaseIGameObject(); return true; }
bool Optimizer:: dumpPhysXCookMesh(IGameNode* gameNode, const std::string& nodeName, int flag) { // 受缩放影响 GMatrix worldTM = gameNode->GetWorldTM(); Point3 scale = worldTM.Scaling(); // 世界矩阵的逆矩阵 GMatrix nodeInvWorldTM = gameNode->GetWorldTM().Inverse(); IGameObject* gameObject = gameNode->GetIGameObject(); IGameMesh* gameMesh = static_cast<IGameMesh*>(gameObject); gameMesh->InitializeData(); int numFaces = gameMesh->GetNumberOfFaces(); int numVertex = numFaces * 3; std::vector<physx::PxVec3> pxVertices; pxVertices.reserve(numVertex); oiram::IndexBuffer indexBuffer; indexBuffer.use32BitIndices = numVertex > 65535; indexBuffer.use32BitIndices ? indexBuffer.uiIndexBuffer.reserve(numVertex) : indexBuffer.usIndexBuffer.reserve(numVertex); for (int i = 0; i < numFaces; ++i) { FaceEx* face = gameMesh->GetFace(i); for (int v = 0; v < 3; ++v) { Point3 position = gameMesh->GetVertex(face->vert[v], false); position = position * nodeInvWorldTM; pxVertices.push_back(physx::PxVec3(position.x * scale.x, position.y * scale.y, position.z * scale.z)); if (indexBuffer.use32BitIndices) indexBuffer.uiIndexBuffer.push_back(static_cast<unsigned int>(indexBuffer.uiIndexBuffer.size())); else indexBuffer.usIndexBuffer.push_back(static_cast<unsigned short>(indexBuffer.usIndexBuffer.size())); } } gameNode->ReleaseIGameObject(); // 初始化physx对象 physx::PxDefaultAllocator s_defAlloc; PxOiramErrorCallback s_defErrCb; physx::PxFoundation* pFound = PxCreateFoundation(PX_PHYSICS_VERSION, s_defAlloc, s_defErrCb); physx::PxCooking* pCooking = PxCreateCooking(PX_PHYSICS_VERSION, *pFound, physx::PxCookingParams()); // 优化物理模型顶点 optimizePhysXMesh(flag, mD3DDevice, mEpsilon, pxVertices, indexBuffer); bool success = false; PxCookMesh cookMesh; switch (flag) { // cookConvexMesh case 1: default: { physx::PxConvexMeshDesc meshDesc; meshDesc.points.data = pxVertices.data(); meshDesc.points.count = static_cast<physx::PxU32>(pxVertices.size()); meshDesc.points.stride = sizeof(physx::PxVec3); meshDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX; // 先尝试导出 success = meshDesc.isValid() && pCooking->cookConvexMesh(meshDesc, cookMesh); if (!success) { // polygon数量大于255的时候需要加上eINFLATE_CONVEX meshDesc.flags |= physx::PxConvexFlag::eINFLATE_CONVEX; success = meshDesc.isValid() && pCooking->cookConvexMesh(meshDesc, cookMesh); } } break; // cookTriangleMesh case 2: { physx::PxTriangleMeshDesc meshDesc; meshDesc.points.data = pxVertices.data(); meshDesc.points.count = static_cast<physx::PxU32>(pxVertices.size()); meshDesc.points.stride = sizeof(physx::PxVec3); if (indexBuffer.use32BitIndices) { meshDesc.triangles.data = indexBuffer.uiIndexBuffer.data(); meshDesc.triangles.count = static_cast<physx::PxU32>(indexBuffer.uiIndexBuffer.size()) / 3; meshDesc.triangles.stride = sizeof(physx::PxU32) * 3; } else { meshDesc.triangles.data = indexBuffer.usIndexBuffer.data(); meshDesc.triangles.count = static_cast<physx::PxU16>(indexBuffer.usIndexBuffer.size()) / 3; meshDesc.triangles.stride = sizeof(physx::PxU16) * 3; meshDesc.flags = physx::PxMeshFlag::e16_BIT_INDICES; } success = meshDesc.isValid(); success = success && pCooking->cookTriangleMesh(meshDesc, cookMesh); } break; } if (success) { std::string pxName = nodeName + ".px"; LogManager::getSingleton().logMessage(false, "Exporting: %s", pxName.c_str()); pxName = config.exportPath + pxName; FILE* fp = fopen(pxName.c_str(), "wb"); if (fp) { fwrite(cookMesh.getData(), cookMesh.getSize(), 1, fp); fclose(fp); } } pCooking->release(); pFound->release(); return success; }
void Unreal3DExport::GetTris() { // Export triangle data FJSMeshTri nulltri = FJSMeshTri(); for( int n=0; n<Nodes.Count(); ++n ) { CheckCancel(); IGameNode* node = Nodes[n]; IGameMesh* mesh = static_cast<IGameMesh*>(node->GetIGameObject()); if( mesh->InitializeData() ) { int vertcount = mesh->GetNumberOfVerts(); int tricount = mesh->GetNumberOfFaces(); if( vertcount > 0 && tricount > 0 ) { // Progress ProgressMsg.printf(GetString(IDS_INFO_MESH),n+1,Nodes.Count(),TSTR(node->GetName())); pInt->ProgressUpdate(Progress+(static_cast<float>(n)/Nodes.Count()*U3D_PROGRESS_MESH), FALSE, ProgressMsg.data()); // Alloc triangles space Tris.Resize(Tris.Count()+tricount); // Append triangles for( int i=0; i!=tricount; ++i ) { FaceEx* f = mesh->GetFace(i); if( f ) { FJSMeshTri tri(nulltri); // TODO: add material id listing RegisterMaterial( node, mesh, f, &tri ); tri.iVertex[0] = VertsPerFrame + f->vert[0]; tri.iVertex[1] = VertsPerFrame + f->vert[1]; tri.iVertex[2] = VertsPerFrame + f->vert[2]; Point2 p; if( mesh->GetTexVertex(f->texCoord[0],p) ){ tri.Tex[0] = FMeshUV(p); } if( mesh->GetTexVertex(f->texCoord[1],p) ){ tri.Tex[1] = FMeshUV(p); } if( mesh->GetTexVertex(f->texCoord[2],p) ){ tri.Tex[2] = FMeshUV(p); } Tris.Append(1,&tri); } } VertsPerFrame += vertcount; } else { // remove invalid node Nodes.Delete(n--,1); } } node->ReleaseIGameObject(); } Progress += U3D_PROGRESS_MESH; }
void MeshExporter::ExtractMesh(IGameNode * node) { IGameObject* obj = node->GetIGameObject(); // export option bool expColor = ExportConfig::Instance()->IsExportColor(); bool expNormal = ExportConfig::Instance()->IsExportNormal(); bool expTexcoord = ExportConfig::Instance()->IsExportTexcoord(); bool expLightmapUV = ExportConfig::Instance()->IsExportLightmapUV(); obj->InitializeData(); const char * nodeName = node->GetName(); IGameNode * parent = node->GetNodeParent(); IGameMesh::ObjectTypes type = obj->GetIGameType(); if (type == IGameMesh::IGAME_MESH) { IGameMesh* mesh = (IGameMesh*) obj; Tab<int> texMaps = mesh->GetActiveMapChannelNum(); mMeshData.VertexElems |= MeshSerializer::VE_POSITION; // position for (int i = 0; i < mesh->GetNumberOfVerts(); ++i) mMeshData.P.PushBack(Utility::ToFloat3(mesh->GetVertex(i))); // vertex color for (int i = 0; expColor && i < mesh->GetNumberOfColorVerts(); ++i) { Point3 c = mesh->GetColorVertex(i); float a = mesh->GetAlphaVertex(i); mMeshData.C.PushBack(Float4(c.x, c.y, c.z, a)); mMeshData.VertexElems |= MeshSerializer::VE_COLOR; } // normal for (int i = 0; expNormal && i < mesh->GetNumberOfNormals(); ++i) { mMeshData.N.PushBack(Utility::ToFloat3(mesh->GetNormal(i))); mMeshData.VertexElems |= MeshSerializer::VE_NORMAL; } // uv for (int i = 0; expTexcoord && texMaps.Count() > 1 && i < mesh->GetNumberOfMapVerts(texMaps[1]); ++i) { Point3 tv = mesh->GetMapVertex(texMaps[1], i); mMeshData.UV.PushBack(Float2(tv.x, 1 - tv.y)); mMeshData.VertexElems |= MeshSerializer::VE_TEXCOORD; } // light map uv for (int i = 0; expLightmapUV && texMaps.Count() > 2 && i < mesh->GetNumberOfMapVerts(texMaps[2]); ++i) { Point3 tv = mesh->GetMapVertex(texMaps[2], i); mMeshData.LUV.PushBack(Float2(tv.x, 1 - tv.y)); mMeshData.VertexElems |= MeshSerializer::VE_LIGHTMAPUV; } IGameSkin * skin = obj->GetIGameSkin(); if (skin != NULL) _dumpSkinInfo(skin); else if (parent != NULL && parent->GetIGameObject()->GetIGameType() == IGameMesh::IGAME_BONE) _genSkinInfo(parent); _dumpMeshBuffer(mesh); mMeshData.Clear(); } for(int i=0;i<node->GetChildCount();i++) { IGameNode * child = node->GetNodeChild(i); // we deal with targets in the light/camera section if(child->IsTarget()) continue; ExtractMesh(child); } node->ReleaseIGameObject(); }
int MaxExporter::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options) { /*if(!suppressPrompts) DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PANEL), GetActiveWindow(), MaxExporterOptionsDlgProc, (LPARAM)this);*/ #pragma message(TODO("return TRUE If the file is exported properly")) Node::s_nextID = 1; ofstream myFile; myFile.open("DebugExporter.txt"); wstring wFileName( name ); string fileName( wFileName.begin(), wFileName.end() ); //f= fopen( fileName.c_str(),"wb"); BinaryFile = loadSave( fileName.c_str() ); //BinaryFile.saveInt( 5 ); //BinaryFile.close(); myFile << "Start Export\n"; IGameScene* gameScene = GetIGameInterface(); gameScene->InitialiseIGame(); int nodeCount = gameScene->GetTopLevelNodeCount(); myFile << "Number of top level nodes: " << nodeCount << "\n"; //get all of the materials for( int nodeNumber = 0; nodeNumber < nodeCount; ++nodeNumber) { IGameNode* gameNode = gameScene->GetTopLevelNode( nodeNumber ); Node* myNode = new Node( gameNode ); m_NodeList.push_back( myNode ); findFaces( myNode, myFile ); } myFile << "Number of materials\n"; myFile << m_materialSet.size() << "\n"; int totalBatches = 0; //myFile<< "Number of triangleBatchMaps: " << m_triangleBatchesPerNode.size() << "\n"; for( auto nodeIter = m_NodeList.begin(); nodeIter != m_NodeList.end(); ++nodeIter ) { std::map< IGameMaterial*, TriangleBatch* > triangleBatches = (*nodeIter)->m_triangleBatchesPerMaterial; myFile << "Invidiual triangleBatch size: " << triangleBatches.size() << "\n"; for( auto materialIter = m_materialSet.begin(); materialIter != m_materialSet.end(); ++materialIter ) { auto found = triangleBatches.find( * materialIter ); if( found != triangleBatches.end() ) { ++totalBatches; } } } BinaryFile.saveInt( m_NodeList.size() ); myFile << "Number of Nodes: " << m_NodeList.size() << "\n"; for( auto nodeIter = m_NodeList.begin(); nodeIter != m_NodeList.end(); ++nodeIter ) { std::map< IGameMaterial*, TriangleBatch* > triangleBatches = (*nodeIter)->m_triangleBatchesPerMaterial; std::map<IGameMaterial*, std::vector< NodeFace > > facesPerMaterial = (*nodeIter)->m_facesPerMaterial; IGameNode* currentNode = (*nodeIter)->m_gameNode; IGameNode* parentNode; GMatrix parentWTM; GMatrix toParentMatrix; GMatrix worldTM; GMatrix localTM; int time = gameScene->GetSceneStartTime(); for( ; time < gameScene->GetSceneEndTime(); time += 4800/30 ) { if( (*nodeIter)->m_parentID != 0 ) { myFile << "Trying to find parent... \n"; parentNode = (*nodeIter)->m_parent->m_gameNode; if( parentNode != nullptr ) { myFile << "Parent found \n"; parentWTM = parentNode->GetWorldTM( time ); toParentMatrix = parentWTM.Inverse(); worldTM = currentNode->GetWorldTM( time ) * toParentMatrix; } } else { worldTM = currentNode->GetWorldTM( time ); } (*nodeIter)->m_toParentMatrix.push_back( Matrix4x4( worldTM[0], worldTM[1], worldTM[2], worldTM[3] ) ); } localTM = currentNode->GetWorldTM().Inverse(); (*nodeIter)->m_worldToLocal = Matrix4x4( localTM[0], localTM[1], localTM[2], localTM[3] ); //Save the node BinaryFile.saveNode( *nodeIter, myFile ); BinaryFile.saveInt( (*nodeIter)->m_triangleBatchesPerMaterial.size() ); for( auto materialIter = m_materialSet.begin(); materialIter != m_materialSet.end(); ++materialIter ) { //Set the current material's VBO and IBO // IGameMaterial* currentMaterial = *materialIter; TriangleBatch* currentBatch = triangleBatches[ currentMaterial ]; GMatrix localTMNoTrans = localTM; localTMNoTrans.SetRow( 3, Point4( 0,0,0,1) ); if( currentBatch != nullptr ) { MaxMaterial* currentMaxMaterial = currentBatch->m_material; VBO* currentVBO = currentBatch->m_vbo; IBO* currentIBO = currentBatch->m_ibo; vector< NodeFace >& faceVector = facesPerMaterial.find( currentMaterial )->second; //Get texture materials and export them // if( currentMaterial != nullptr ) { int numOfTexMaps = currentMaterial->GetNumberOfTextureMaps(); myFile << "Number of texture maps: " << numOfTexMaps << "\n"; for( int i = 0; i < numOfTexMaps; ++i ) { IGameTextureMap* gameTextureMap = currentMaterial->GetIGameTextureMap( i ); if( gameTextureMap != nullptr && gameTextureMap->IsEntitySupported() ) { int stdMapSlot = gameTextureMap->GetStdMapSlot(); if( stdMapSlot == ID_DI ) { wstring wBitmapFileName; wBitmapFileName = gameTextureMap->GetBitmapFileName(); if( wBitmapFileName.size() > 0 ) { BitmapInfo bi( gameTextureMap->GetBitmapFileName() ); BMMGetFullFilename( &bi ); wBitmapFileName = bi.Name(); std::string fullBitmapFileName( wBitmapFileName.begin(), wBitmapFileName.end() ); if( fullBitmapFileName.size() > 0 ) { int lastSlash = fullBitmapFileName.find_last_of('\\') + 1; if( lastSlash != string::npos ) { const std::string bitmapFileName = fullBitmapFileName.substr( lastSlash ); wstring nameAsWString( name ); std::string nameAsString( nameAsWString.begin(), nameAsWString.end() ); const std::string extension = nameAsString.substr( 0, nameAsString.find_last_of('\\') + 1 ); std::string newFileName = extension; newFileName.append( bitmapFileName ); wstring wNewFileName(newFileName.begin(), newFileName.end()); if( CopyFile( wBitmapFileName.c_str(), wNewFileName.c_str(), false ) ) { if( stdMapSlot == ID_DI ) { currentMaxMaterial->m_diffuseTexture = bitmapFileName; currentMaxMaterial->bHasDiffuseTexture = true; } //BinaryFile.saveString( bitmapFileName ); } else { myFile << GetLastError() << "\n"; myFile << "copying the file FAILED.\n"; } } } } } } } } myFile<< "Number of faces for this material: " << faceVector.size() << "\n"; for( int face = 0; face < faceVector.size(); ++face ) { FaceEx* meshFace = faceVector[face].m_face; IGameMesh* gameMesh = faceVector[face].m_mesh; IGameSkin* gameSkin = gameMesh->GetIGameSkin(); int position, normal, color, texCoordinate, maxPosition; for( int i = 0; i < 3; ++i) { maxPosition = (int)meshFace->vert[i]; Point3 tempPos = gameMesh->GetVertex( maxPosition ); tempPos = tempPos * localTM; Vector3D positionVec3( tempPos.x, tempPos.y, tempPos.z ); position = currentVBO->insertPosition(positionVec3); normal = (int)meshFace->norm[i]; Point3 tempNormal = gameMesh->GetNormal( normal ); tempNormal = tempNormal * localTMNoTrans; tempNormal = tempNormal.Normalize(); Vector3D normalVec3( tempNormal.x, tempNormal.y, tempNormal.z ); normal = currentVBO->insertNormal(normalVec3); //IBO texCoordinate = (int)meshFace->texCoord[i]; Point2 tempTexCoord = gameMesh->GetTexVertex( texCoordinate ); Vector2 texCoordVec2( tempTexCoord.x, tempTexCoord.y ); texCoordinate = currentVBO->insertTexCoord(texCoordVec2); VertexIndex VI( position, normal, texCoordinate ); if( gameSkin != nullptr ) { int numberOfBones = gameSkin->GetNumberOfBones( maxPosition ); for( int boneIndex = 0; boneIndex < numberOfBones; ++boneIndex ) { float boneWeight = gameSkin->GetWeight( maxPosition, boneIndex ); IGameNode* bone = gameSkin->GetIGameBone( maxPosition, boneIndex ); myFile << "Bone node ID: " << bone->GetNodeID() << "\n"; int nodeIDForBone = m_boneIDToNodeID[ bone->GetNodeID() ]; myFile << "Node ID: " << nodeIDForBone << "\n"; VI.addBoneWeight( nodeIDForBone, boneWeight ); /*for( auto boneIter = m_NodeList.begin(); boneIter != m_NodeList.end(); ++boneIter ) { if( (*boneIter)->m_gameNode == bone ) { myFile << "Found the bone!\n"; } }*/ } VI.topBoneWeights(); } int vertIndex = currentVBO->insertVertex( VI ); currentIBO->addIndex( vertIndex ); } } BinaryFile.saveTriangleMesh( currentBatch, myFile ); } } } myFile.close(); for( int nodeNumber = 0; nodeNumber < nodeCount; ++nodeNumber) { IGameNode* gameNode = gameScene->GetTopLevelNode( nodeNumber ); if( gameNode != nullptr ) { tearDown( gameNode ); } } BinaryFile.close(); return TRUE; //return FALSE; }
void MaxExporter::findFaces( Node* myNode, ofstream& myFile ) { myFile << "NewNode\n"; if( myNode != nullptr && myNode->m_gameNode != nullptr ) { IGameObject* gameObject = myNode->m_gameNode->GetIGameObject(); if( gameObject != nullptr ) { m_boneIDToNodeID[ myNode->m_gameNode->GetNodeID() ] = myNode->m_id; //gameObject->InitializeData(); if( gameObject->GetIGameType() == IGameObject::IGAME_MESH ) { myFile << "Is a game mesh \n"; IGameMesh* gameMesh = (IGameMesh*)gameObject; if( gameMesh != nullptr) { gameMesh->InitializeData(); int numberOfFaces = gameMesh->GetNumberOfFaces(); //std::map< IGameMaterial*, TriangleBatch* > triangleBatches; //std::map<IGameMaterial*, std::vector< NodeFace > > nodeFacePerMat; for( int i = 0; i < numberOfFaces; ++i ) { FaceEx* meshFace = gameMesh->GetFace( i ); NodeFace nodeFace( gameMesh, meshFace ); IGameMaterial* gameMaterial = gameMesh->GetMaterialFromFace( meshFace ); m_materialSet.insert( gameMaterial ); auto found = myNode->m_triangleBatchesPerMaterial.find( gameMaterial ); if( found == myNode->m_triangleBatchesPerMaterial.end() ) { MaxMaterial* material = new MaxMaterial( gameMaterial ); myNode->m_triangleBatchesPerMaterial[ gameMaterial ] = new TriangleBatch( material, new VBO(), new IBO() ); std::vector< NodeFace > faces; faces.push_back(nodeFace); myNode->m_facesPerMaterial[ gameMaterial ] = faces; } else { auto findFace = myNode->m_facesPerMaterial.find( gameMaterial ); findFace->second.push_back( nodeFace ); } } //myNode->addNodeFaces( nodeFacePerMat ); //m_triangleBatchesPerNode[gameNode] = triangleBatches; } } } int childCount = myNode->m_gameNode->GetChildCount(); myFile<< childCount << "\n"; for( int j = 0; j < childCount; ++j ) { IGameNode* childGameNode = myNode->m_gameNode->GetNodeChild( j ); if( childGameNode != nullptr ) { Node* childNode = new Node( childGameNode ); childNode->setParent( myNode ); m_NodeList.push_back( childNode ); findFaces( childNode, myFile ); } } //gameNode->ReleaseIGameObject(); } }