예제 #1
0
// [HACK] Wow, "GMatrix::Inverse()" appears to be buggy...
GMatrix PLTools::Inverse(const GMatrix &mMatrix)
{
	Matrix3 mMatrix3 = mMatrix.ExtractMatrix3();
	mMatrix3.Invert();
	return mMatrix3;
}
예제 #2
0
//----------------------------------------------------------------------------------
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";
}