Пример #1
0
        private void CreateCMPData(FBXNode n)
        {
            Vector3 vOffset = Vector3.Zero;

            CmpndData cmpnd = new CmpndData();

            cmpnd.index       = 0;
            cmpnd.object_name = n.GetName();
            if (cmpnd.object_name == "Root")
            {
                cmpnd.name = "Root";
            }
            else
            {
                cmpnd.name = "Part_" + cmpnd.object_name;

                if (Relocate)
                {
                    vOffset = T(n.EvaluateLocalTranslation(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false));
                }
            }

            cmpnd.object_data      = new ThreeDBData();
            cmpnd.object_data.data = new LodData[8];

            cmpnd.object_data.wireframe_lod = 0;

            int lods = 0;

            for (int i = 0; i < n.GetChildCount(); i++)
            {
                var cur_lodnode = n.GetChild(i);

                var match = Regex.Match(cur_lodnode.GetName(), @"^.+_lod(?<lod>[0-9])(?<wireframe>_vwd)?");
                if (match.Success)
                {
                    uint lod = uint.Parse(match.Groups["lod"].Value);
                    if (match.Groups["wireframe"].Success)
                    {
                        cmpnd.object_data.wireframe_lod = lod;
                    }

                    cmpnd.object_data.data[lod].meshes = new List <SMesh>();

                    lods++;

                    int numVerts = 0;
                    int numFaces = 0;

                    Vector3 bbmin = new Vector3(float.MaxValue);
                    Vector3 bbmax = new Vector3(float.MinValue);

                    for (int j = 0; j < cur_lodnode.GetChildCount(); j++)
                    {
                        var cur_node = cur_lodnode.GetChild(j);

                        var attr = cur_node.GetNodeAttribute();
                        if (attr == null)
                        {
                            continue;
                        }

                        if (attr.GetAttributeType() != ArcManagedFBX.Types.EAttributeType.eMesh)
                        {
                            continue;
                        }

                        var pmesh = attr as FBXMesh;

                        var cur_node_trans = T(cur_node.EvaluateGlobalTransform(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false));
                        var cur_node_geo   = T(cur_node.GetGeometricMatrix(ArcManagedFBX.Types.EPivotSet.eSourcePivot));
                        cur_node_trans = cur_node_geo * cur_node_trans;

                        SMesh mesh = new SMesh();

                        int nTris = pmesh.GetPolygonCount();
                        if (nTris <= 0)
                        {
                            continue;
                        }

                        if (cur_node.GetMaterialCount() <= 0)
                        {
                            mesh.material_name = "default";
                        }
                        else
                        {
                            var material = cur_node.GetMaterial(0);
                            mesh.material_name = material.GetName();
                        }

                        mesh.name = cur_node.GetName();

                        mesh.t = new VMSTri[nTris];
                        int nVerts = nTris * 3;
                        mesh.v = new VMSVert[nVerts];

                        var vertices           = pmesh.GetControlPoints();
                        int tangentLayerCount  = pmesh.GetElementTangentCount();
                        var tangentLayer       = tangentLayerCount > 0 ? pmesh.GetElementTangent().GetDirectArray() : null;
                        int binormalLayerCount = pmesh.GetElementBinormalCount();
                        var binormalLayer      = binormalLayerCount > 0 ? pmesh.GetElementBinormal().GetDirectArray() : null;

                        for (int nTri = 0; nTri < nTris; nTri++)
                        {
                            mesh.t[nTri].vertices = new ushort[3];

                            for (int k = 0; k < 3; k++)
                            {
                                int nVert = (nTri * 3 + k);

                                Vector3   vertice, normal;
                                Vector2   uv;
                                bool      unmapped  = false;
                                FBXVector fbxuv     = new FBXVector();
                                FBXVector fbxnormal = new FBXVector();

                                vertice = Vector3.TransformCoordinate(T(vertices[pmesh.GetPolygonVertex(nTri, k)]), cur_node_trans);

                                // offset vertice
                                vertice -= vOffset;
                                pmesh.GetPolygonVertexUV(nTri, k, "map1", ref fbxuv, ref unmapped);
                                uv = T2(fbxuv);
                                pmesh.GetPolygonVertexNormal(nTri, k, ref fbxnormal);
                                normal = Vector3.TransformNormal(T(fbxnormal), cur_node_trans);

                                mesh.t[nTri].vertices[k] = (ushort)nVert;

                                mesh.v[nVert].vert   = vertice;
                                mesh.v[nVert].normal = normal;
                                mesh.v[nVert].uv     = uv;

                                mesh.v[nVert].tangent = tangentLayer != null?T(tangentLayer.GetAt(nVert)) : Vector3.Zero;

                                mesh.v[nVert].binormal = binormalLayer != null?T(binormalLayer.GetAt(nVert)) : Vector3.Zero;

                                /*
                                 *
                                 * float alpha = 1.0f;
                                 * int iVCindex = mesh->pMesh->GetFaceVertex(pTriangle->meshFaceIndex, i);
                                 * if (iVCindex != -1)
                                 * {
                                 *  alpha = mesh->pMesh->GetAlphaVertex(pTriangle->alpha[i]);
                                 *  color = mesh->pMesh->GetColorVertex(pTriangle->color[i]);
                                 *  mesh->v[nVert].diffuse = (DWORD)(alpha * 255) << 24 | (DWORD)(color.x * 255) << 16 | (DWORD)(color.y * 255) << 8 | (DWORD)(color.z * 255);
                                 *  mesh->v[nVert].uv = uv;
                                 * }
                                 * else
                                 * {
                                 *  mesh->v[nVert].tangent = Point3(0, 0, 0);
                                 *  mesh->v[nVert].binormal = Point3(0, 0, 0);
                                 * }*/

                                bbmin = Vector3.Min(bbmin, vertice);
                                bbmax = Vector3.Max(bbmin, vertice);
                            }
                        }

                        mesh.nVerts = nVerts;
                        numVerts   += mesh.nVerts;

                        mesh.nTris = nTris;
                        numFaces  += mesh.nTris;

                        cmpnd.object_data.data[lod].meshes.Add(mesh);
                    }

                    cmpnd.object_data.data[lod].vmeshref = new VMeshRef();
                    cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxX = bbmax.X;
                    cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxY = bbmax.Y;
                    cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxZ = bbmax.Z;
                    cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinX = bbmin.X;
                    cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinY = bbmin.Y;
                    cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinZ = bbmin.Z;
                    var vCenter = (bbmax + bbmin) / 2;
                    cmpnd.object_data.data[lod].vmeshref.CenterX = vCenter.X;
                    cmpnd.object_data.data[lod].vmeshref.CenterY = vCenter.Y;
                    cmpnd.object_data.data[lod].vmeshref.CenterZ = vCenter.Z;
                    cmpnd.object_data.data[lod].vmeshref.Radius  = (bbmax - vCenter).Length() * 1.25f;

                    cmpnd.object_data.data[lod].vmeshref.HeaderSize = 60;
                    cmpnd.object_data.data[lod].vmeshref.NumMeshes  = (ushort)cmpnd.object_data.data[lod].meshes.Count;
                    cmpnd.object_data.data[lod].vmeshref.NumVert    = (ushort)numVerts;
                    cmpnd.object_data.data[lod].vmeshref.NumIndex   = (ushort)(numFaces * 3);

                    if (numFaces * 3 > 0xFFFF)
                    {
                        throw new ArgumentException($"{cmpnd.object_name} references more than 65535 vertices. Split the group into smaller groups!");
                    }
                }
            }

            cmpnd.object_data.lods = (uint)lods;
            cmpnd.index            = cmpndData.Count;
            cmpndData.Add(cmpnd);

            if (cmpnd.object_name != "Root")
            {
                if (cmpnd.object_name.EndsWith("_rev"))
                {
                    CmpRevData.Part revdata = new CmpRevData.Part();
                    revdata.ParentName = "Root";
                    revdata.ChildName  = cmpnd.object_name;

                    revdata.OriginX = vOffset.X;
                    revdata.OriginY = vOffset.Y;
                    revdata.OriginZ = vOffset.Z;

                    var mat = n.EvaluateLocalTransform(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false);
                    revdata.RotMatXX = (float)mat.mData[0].x;
                    revdata.RotMatXY = (float)mat.mData[1].x;
                    revdata.RotMatXZ = (float)mat.mData[2].x;
                    revdata.RotMatYX = (float)mat.mData[0].y;
                    revdata.RotMatYY = (float)mat.mData[1].y;
                    revdata.RotMatYZ = (float)mat.mData[2].y;
                    revdata.RotMatZX = (float)mat.mData[0].z;
                    revdata.RotMatZY = (float)mat.mData[1].z;
                    revdata.RotMatZZ = (float)mat.mData[2].z;

                    revdata.AxisRotX = (float)mat.mData[0].x;
                    revdata.AxisRotY = (float)mat.mData[1].x;
                    revdata.AxisRotZ = (float)mat.mData[2].x;
                    revdata.Max      = 1;

                    rev.Parts.Add(revdata);
                }
                else if (cmpnd.object_name.EndsWith("_pris"))
                {
                    CmpRevData.Part revdata = new CmpRevData.Part();
                    revdata.ParentName = "Root";
                    revdata.ChildName  = cmpnd.object_name;

                    revdata.OriginX = vOffset.X;
                    revdata.OriginY = vOffset.Y;
                    revdata.OriginZ = vOffset.Z;

                    revdata.RotMatXX = revdata.RotMatYY = revdata.RotMatZZ = 1;

                    revdata.AxisRotZ = 1;
                    revdata.Max      = 360;

                    pris.Parts.Add(revdata);
                }
                else
                {
                    CmpFixData.Part fixdata = new CmpFixData.Part();
                    fixdata.ParentName = "Root";
                    fixdata.ChildName  = cmpnd.object_name;

                    fixdata.OriginX = vOffset.X;
                    fixdata.OriginY = vOffset.Y;
                    fixdata.OriginZ = vOffset.Z;

                    fixdata.RotMatXX = fixdata.RotMatYY = fixdata.RotMatZZ = 1;

                    fix.Parts.Add(fixdata);
                }
            }
        }