// [HACK] Wow, "GMatrix::Inverse()" appears to be buggy... GMatrix PLTools::Inverse(const GMatrix &mMatrix) { Matrix3 mMatrix3 = mMatrix.ExtractMatrix3(); mMatrix3.Invert(); return mMatrix3; }
//---------------------------------------------------------------------------------- bool DumpModel(IGameMesh *gM, m_model *pModel, IGameNode *pGameNode) { IGameSkin *skin = NULL; if (gM->InitializeData()) // prepare game data { GMatrix ObjectTM = pGameNode->GetObjectTM(ExporterMAX::GetExporter()->GetStaticFrame()); Matrix3 world_to_obj = Inverse(ObjectTM.ExtractMatrix3()); AffineParts PRS; decomp_affine(ObjectTM.ExtractMatrix3(), &PRS); //Matrix xform; // //xform.set_rot(Quaternion(-PRS.q.x, -PRS.q.z, PRS.q.y, PRS.q.w)); //xform.set_translation(Vector(-PRS.t.x, PRS.t.z, PRS.t.y)); const int numMod = gM->GetNumModifiers(); if (numMod > 0) { for (int i = 0; i < numMod; i++) // check for skin modifier { IGameModifier * pM = gM->GetIGameModifier(i); if (pM->IsSkin()) { skin = (IGameSkin*)pM; // skin modifier } } } mesh_opt *m_opt; TriMapType tri_map; MatFaceMapType matface_map; // int <-> material unsigned int max_face_idx = 0; unsigned int FaceNum = Helper_GetNumberOfFaces(gM, FaceNum, max_face_idx); for (size_t i = 0; i < FaceNum; ++i) { Helper_ProcessFace(gM, i, PRS, world_to_obj, matface_map, tri_map, max_face_idx); } Helper_ComputeNormals(gM, matface_map); for (size_t IndexAdd = 0; IndexAdd < tri_map.size(); ++IndexAdd) { pModel->meshes.push_back(new m_mesh()); } int count = 0; TriMapIt it = tri_map.begin(); while (it != tri_map.end()) { m_mesh &msh = *pModel->meshes[count]; msh.num_faces = (*it).second->size() / 3; msh.material_id = (*it).first; msh.faces_idx = new unsigned int[msh.num_faces * 3]; for (size_t i = 0; i < msh.num_faces * 3; i+=3) { int Idx0 = (*it).second->front(); (*it).second->pop_front(); int Idx1 = (*it).second->front(); (*it).second->pop_front(); int Idx2 = (*it).second->front(); (*it).second->pop_front(); msh.faces_idx[i+0] = Idx2; msh.faces_idx[i+1] = Idx1; msh.faces_idx[i+2] = Idx0; } MatFaceMapIt it_mapfacemap = matface_map.find((*it).first); assert(it_mapfacemap != matface_map.end()); m_opt = (*it_mapfacemap).second; msh.skin = skin ? true : false; msh.num_vertices = m_opt->face_map.size(); msh.vertices = new Vector[msh.num_vertices]; msh.normals = new Vector[msh.num_vertices]; msh.colors = new Vector4f[msh.num_vertices]; msh.weights = skin ? new Vector4f[msh.num_vertices] : NULL; msh.bone_idxs = skin ? new unsigned int[msh.num_vertices * 4] : NULL; unsigned int texdim = 0; bool * faceidx_cache = new bool[msh.num_vertices]; memset(faceidx_cache, 0, msh.num_vertices * sizeof(bool)); bool alloc_texture = false; for (size_t i = 0; i < msh.num_faces * 3; ++i) { unsigned int face_idx = msh.faces_idx[i]; FaceMapIt it_face_map = m_opt->face_map.find(face_idx); assert(it_face_map != m_opt->face_map.end()); vert_opt face = (*it_face_map).second; msh.faces_idx[i] = face.face_idx; if (faceidx_cache[face.face_idx] == false) { faceidx_cache[face.face_idx] = true; msh.vertices[face.face_idx] = Vector(face.v.x, face.v.y, face.v.z); msh.colors[face.face_idx].x = face.c.x; msh.colors[face.face_idx].y = face.c.y; msh.colors[face.face_idx].z = face.c.z; Vector V(face.n.x, face.n.y, face.n.z); V.normalize(); msh.normals[face.face_idx] = V; if (msh.skin) { msh.weights[face.face_idx].x = face.weights.x; msh.weights[face.face_idx].y = face.weights.y; msh.weights[face.face_idx].z = face.weights.z; msh.bone_idxs[face.face_idx * 4 + 0] = face.bones[0]; // already remapped idxs msh.bone_idxs[face.face_idx * 4 + 1] = face.bones[1]; msh.bone_idxs[face.face_idx * 4 + 2] = face.bones[2]; msh.bone_idxs[face.face_idx * 4 + 3] = face.bones[3]; } if (face.num_tmaps && alloc_texture == false) { alloc_texture = true; texdim = 2; msh.num_texcoord_sets = face.num_tmaps; msh.texcoord_sets = new m_texcoord_set[msh.num_texcoord_sets]; for (size_t j = 0; j < face.num_tmaps; ++j) { msh.texcoord_sets[j].dim = texdim; msh.texcoord_sets[j].texcoords = new float[msh.num_vertices * texdim]; } } for (size_t j = 0; j < face.num_tmaps; ++j) { msh.texcoord_sets[j].texcoords[face.face_idx * texdim] = face.tmaps[j].x; msh.texcoord_sets[j].texcoords[face.face_idx * texdim + 1] = face.tmaps[j].y; } Vector tmp = face.v; //transform_coord(face.v, xform); //mult_pos(tmp, xform, face.v); // aabb min... if (tmp.x < pModel->aabb_min.x) pModel->aabb_min.x = tmp.x; if (tmp.y < pModel->aabb_min.y) pModel->aabb_min.y = tmp.y; if (tmp.z < pModel->aabb_min.z) pModel->aabb_min.z = tmp.z; // aabb max... if (tmp.x > pModel->aabb_max.x) pModel->aabb_max.x = tmp.x; if (tmp.y > pModel->aabb_max.y) pModel->aabb_max.y = tmp.y; if (tmp.z > pModel->aabb_max.z) pModel->aabb_max.z = tmp.z; // mesh bounding box // aabb min... if (tmp.x < msh.aabb_min.x) msh.aabb_min.x = tmp.x; if (tmp.y < msh.aabb_min.y) msh.aabb_min.y = tmp.y; if (tmp.z < msh.aabb_min.z) msh.aabb_min.z = tmp.z; // aabb max... if (tmp.x > msh.aabb_max.x) msh.aabb_max.x = tmp.x; if (tmp.y > msh.aabb_max.y) msh.aabb_max.y = tmp.y; if (tmp.z > msh.aabb_max.z) msh.aabb_max.z = tmp.z; } } delete [] faceidx_cache; ++count; ++it; Helper_ComputeUV(msh); Helper_ComputeTBN(msh); } return true; } return false; // "BadObject"; }