Ejemplo n.º 1
0
 /// <summary>
 ///     Output the control points that are part of the mesh in question
 /// </summary>
 /// <param name="meshInstance">The instance of the mesh that we are observing</param>
 private static void DisplayControlsPoints(FBXMesh meshInstance)
 {
     if (meshInstance == null)
     {
         throw new ArgumentNullException("The mesh instance specified is null or invalid. Check and try again.");
     }
 }
Ejemplo n.º 2
0
        private void AddMorphToMesh(FBXScene pScene, FBXNode pFbxNode, List <Vector> morph)
        {
            FBXShape lShape = FBXShape.Create(pScene, "MorphShape");
            FBXMesh  mesh   = (FBXMesh)pFbxNode.GetMesh();
            int      count  = mesh.GetControlPointsCount();

            lShape.InitControlPoints(count);
            List <FBXVector4> lControlPoints = lShape.GetControlPoints();

            for (int i = 0; i < count; i++)
            {
                FBXVector4 cp = new FBXVector4(morph[i].members[0] * exportScale,
                                               morph[i].members[1] * exportScale,
                                               morph[i].members[2] * exportScale,
                                               0);
                lControlPoints[i] = cp;
            }
            lShape.SetControlPoints(lControlPoints);

            FBXBlendShape        lBlendShape        = FBXBlendShape.Create(pScene, "morph");
            FBXBlendShapeChannel lBlendShapeChannel = FBXBlendShapeChannel.Create(pScene, "morphchannel");

            mesh.AddDeformer(lBlendShape);
            lBlendShape.AddBlendShapeChannel(lBlendShapeChannel);
            lBlendShapeChannel.AddTargetShape(lShape);
        }
Ejemplo n.º 3
0
        private static void DisplayCamera(FBXMesh meshInstance)
        {
            if (meshInstance == null)
            {
                throw new ArgumentNullException("The mesh instance is null or invalid. Check and try again.");
            }

            Logger.LogMessage("");
        }
Ejemplo n.º 4
0
        private FBXNode CreateFbxMesh(MeshLodSection section, FBXScene pScene)
        {
            FBXMesh fbxMesh = FBXMesh.Create(pScene, section.matName);
            FBXGeometryElementNormal lGeometryElementNormal = fbxMesh.CreateElementNormal();

            lGeometryElementNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementBinormal lGeometryElementBiNormal = fbxMesh.CreateElementBinormal();

            lGeometryElementBiNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent();

            lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            fbxMesh.InitControlPoints(section.vertices.Count);
            FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial();

            lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon);
            lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect);
            FBXGeometryElementUV lUVDiffuseElement = fbxMesh.CreateElementUV(section.matName);

            lUVDiffuseElement.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            lUVDiffuseElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect);
            lUVDiffuseElement.SetIndexArrayCount(section.vertices.Count);
            for (int j = 0; j < section.vertices.Count; j++)
            {
                FBXVector4 position   = new FBXVector4(section.vertices[j].position.members[0] * exportScale, section.vertices[j].position.members[1] * exportScale, section.vertices[j].position.members[2] * exportScale, 0);
                FBXVector4 normal     = new FBXVector4(section.vertices[j].normals.members[0], section.vertices[j].normals.members[1], section.vertices[j].normals.members[2], section.vertices[j].normals.members[3]);
                FBXVector4 textCoords = new FBXVector4(section.vertices[j].texCoords.members[0], (-section.vertices[j].texCoords.members[1] + 1), 0, 0);
                FBXVector4 bitangent  = new FBXVector4(section.vertices[j].biTangents.members[0], section.vertices[j].biTangents.members[1], section.vertices[j].biTangents.members[2], section.vertices[j].biTangents.members[3]);
                FBXVector4 tangent    = new FBXVector4(section.vertices[j].tangents.members[0], section.vertices[j].tangents.members[1], section.vertices[j].tangents.members[2], section.vertices[j].tangents.members[3]);
                fbxMesh.SetControlPoint(j, position);
                lGeometryElementNormal.Add(normal);
                lGeometryElementBiNormal.Add(bitangent);
                lGeometryElementTangent.Add(tangent);
                lUVDiffuseElement.Add(textCoords);
            }

            for (int j = 0; j < section.indicies.Count; j++)
            {
                if (j % 3 == 0)
                {
                    fbxMesh.EndPolygon();
                    fbxMesh.BeginPolygon();
                }
                fbxMesh.AddPolygon(section.indicies[j]);
            }
            fbxMesh.EndPolygon();
            FBXNode lMeshNode = FBXNode.Create(pScene, section.matName);

            lMeshNode.SetNodeAttribute(fbxMesh);
            lMeshNode.AddMaterial(pScene, section.matName);
            return(lMeshNode);
        }
    void ImportSetMesh(string strNodeName, GameObject goNode, GameObject goTopAttachNode, bool bDirectControlPointsMode)
    {
        // Get Mesh
        IntPtr pFBXGetMesh = FBXImporterGetMesh(strNodeName, bInDirectControlPointsMode, bInNormalSmoothing);
        if (pFBXGetMesh != IntPtr.Zero)
        {
            FBXMesh sFBXMesh = new FBXMesh();
            IntPtr pFBXMesh = Marshal.AllocHGlobal(Marshal.SizeOf(sFBXMesh));
            try
            {
                sFBXMesh = (FBXMesh)Marshal.PtrToStructure(pFBXGetMesh, typeof(FBXMesh));
            }
            finally
            {
                Marshal.FreeHGlobal(pFBXMesh);
            }
            if (bDirectControlPointsMode)
            {
                sFBXMesh.numVertexs = sFBXMesh.numVertexs / 3;
                sFBXMesh.numNormals = sFBXMesh.numNormals / 3;
                sFBXMesh.numUVs = sFBXMesh.numUVs / 3;
            }

            // Vertex
            float[] fVertexs = new float[sFBXMesh.numVertexs * 3];
            Marshal.Copy(sFBXMesh.fVertexs, fVertexs, 0, sFBXMesh.numVertexs * 3);
            Vector3[] vecVertexs = new Vector3[sFBXMesh.numVertexs];
            int j = 0;
            for (int i = 0; i < sFBXMesh.numVertexs; i++)
            {
                vecVertexs[i].x = -fVertexs[j] * fGlobalScale;
                j++;
                vecVertexs[i].y = fVertexs[j] * fGlobalScale;
                j++;
                vecVertexs[i].z = fVertexs[j] * fGlobalScale;
                j++;
            }

            // Normal
            float[] fNormals = new float[sFBXMesh.numNormals * 3];
            Marshal.Copy(sFBXMesh.fNormals, fNormals, 0, sFBXMesh.numNormals * 3);
            Vector3[] vecNormals = new Vector3[sFBXMesh.numNormals];
            j = 0;
            for (int i = 0; i < sFBXMesh.numNormals; i++)
            {
                vecNormals[i].x = -fNormals[j];
                j++;
                vecNormals[i].y = fNormals[j];
                j++;
                vecNormals[i].z = fNormals[j];
                j++;
            }

            // UV
            float[] fUVs = new float[sFBXMesh.numUVs * 2];
            Marshal.Copy(sFBXMesh.fUVs, fUVs, 0, sFBXMesh.numUVs * 2);
            Vector2[] vecUVs = new Vector2[sFBXMesh.numUVs];
            j = 0;
            for (int i = 0; i < sFBXMesh.numUVs; i++)
            {
                vecUVs[i].x = fUVs[j];
                j++;
                vecUVs[i].y = fUVs[j];
                j++;
            }

            // Polygon (MaterialID)
            int[] iPolygonMatIDs = new int[sFBXMesh.numPolygonMatID];
            Marshal.Copy(sFBXMesh.iPolygonMatIDs, iPolygonMatIDs, 0, sFBXMesh.numPolygonMatID);
            int numPolygonIndex = sFBXMesh.numPolygonIndex;
            int[] iPolygonIndexs = new int[numPolygonIndex];
            Marshal.Copy(sFBXMesh.iPolygonIndexs, iPolygonIndexs, 0, numPolygonIndex);
            if (bDirectControlPointsMode)
            {
                sFBXMesh.numPolygonMatID = sFBXMesh.numPolygonMatID / 3;
            }

            // Set Mesh
            goNode.AddComponent<MeshRenderer>();
            goNode.AddComponent<MeshFilter>();
            Mesh sMesh = new Mesh();
            sMesh.name = goNode.name;
            goNode.GetComponent<MeshFilter>().mesh = sMesh;
            sMesh.Clear();
            sMesh.vertices = vecVertexs;
            sMesh.normals = vecNormals;
            sMesh.uv = vecUVs;
            sMesh.subMeshCount = sFBXMesh.numMatID;
            List<List<int>> listListMatIDIndeices = new List<List<int>>();
            for (int i = 0; i < sFBXMesh.numMatID; i++)
            {
                List<int> iListMatIDIndeices = new List<int>();
                listListMatIDIndeices.Add(iListMatIDIndeices);
            }

            // Polygon (Material Index)
            if (bDirectControlPointsMode)
            {
                j = 0;
                for (int i = 0; i < sFBXMesh.numPolygonMatID; i++)
                {
                    int iMatID = iPolygonMatIDs[i];
                    if (iMatID < listListMatIDIndeices.Count)
                    {
                        listListMatIDIndeices[iMatID].Add(iPolygonIndexs[j + 0]);
                        listListMatIDIndeices[iMatID].Add(iPolygonIndexs[j + 2]);
                        listListMatIDIndeices[iMatID].Add(iPolygonIndexs[j + 1]);
                        j = j + 3;
                    }
                }
            }
            else
            {
                j = 0;
                for (int i = 0; i < sFBXMesh.numPolygonMatID; i++)
                {
                    int iMatID = iPolygonMatIDs[i];
                    if (iMatID < listListMatIDIndeices.Count)
                    {
                        listListMatIDIndeices[iMatID].Add(j + 0);
                        listListMatIDIndeices[iMatID].Add(j + 2);
                        listListMatIDIndeices[iMatID].Add(j + 1);
                        j = j + 3;
                    }
                }
            }

            // Triangles (Material Index)
            j = 0;
            for (int i = 0; i < sFBXMesh.numMatID; i++)
            {
                int[] iMatIDIndeices = listListMatIDIndeices[i].ToArray();
                //if (iMatIDIndeices.Length > 0)
                {
                    sMesh.SetTriangles(iMatIDIndeices, j);
                    j++;
                }
            }

            // Get Weight
            IntPtr pFBXGetWeight = FBXImporterGetWeight(strNodeName, iPolygonIndexs, numPolygonIndex, bInDirectControlPointsMode);
            if (pFBXGetWeight != IntPtr.Zero)
            {
                FBXWeight sFBXWeight = new FBXWeight();
                IntPtr pFBXWeight = Marshal.AllocHGlobal(Marshal.SizeOf(sFBXWeight));
                try
                {
                    sFBXWeight = (FBXWeight)Marshal.PtrToStructure(pFBXGetWeight, typeof(FBXWeight));
                }
                finally
                {
                    Marshal.FreeHGlobal(pFBXWeight);
                }
                if (bDirectControlPointsMode)
                {
                    sFBXWeight.iBoneWeightCount = sFBXWeight.iBoneWeightCount / 3;
                }

                // Weight (Bone)
                int[] iBoneID = new int[sFBXWeight.iBoneWeightCount * 4];
                Marshal.Copy(sFBXWeight.iBoneID, iBoneID, 0, sFBXWeight.iBoneWeightCount * 4);
                float[] fBoneWeight = new float[sFBXWeight.iBoneWeightCount * 4];
                Marshal.Copy(sFBXWeight.fBoneWeight, fBoneWeight, 0, sFBXWeight.iBoneWeightCount * 4);
                BoneWeight[] boneWeights = new BoneWeight[sFBXWeight.iBoneWeightCount];
                for (int i = 0; i < sFBXWeight.iBoneWeightCount; i++)
                {
                    BoneWeight boneWeight = new BoneWeight();
                    boneWeight.boneIndex0 = iBoneID[(i * 4) + 0];
                    boneWeight.boneIndex1 = iBoneID[(i * 4) + 1];
                    boneWeight.boneIndex2 = iBoneID[(i * 4) + 2];
                    boneWeight.boneIndex3 = iBoneID[(i * 4) + 3];
                    boneWeight.weight0 = fBoneWeight[(i * 4) + 0];
                    boneWeight.weight1 = fBoneWeight[(i * 4) + 1];
                    boneWeight.weight2 = fBoneWeight[(i * 4) + 2];
                    boneWeight.weight3 = fBoneWeight[(i * 4) + 3];
                    boneWeights[i] = boneWeight;
                }
                sMesh.boneWeights = boneWeights;

                // Bind Pose (Bone)
                SkinnedMeshRenderer sSkinnedMeshRenderer = goNode.AddComponent<SkinnedMeshRenderer>();
                string strBoneName = Marshal.PtrToStringAnsi(sFBXWeight.strBoneNodeNames).ToString();
                if (strBoneName != "")
                {
                    string[] strBoneNodeNames = strBoneName.Split(',');
                    //float[] matBonePose = new float[strBoneNodeNames.Length * 16];
                    //Marshal.Copy(sFBXWeight.matBonePose, matBonePose, 0, strBoneNodeNames.Length * 16);
                    Matrix4x4[] bindposes = new Matrix4x4[strBoneNodeNames.Length];
                    Transform[] bones = new Transform[strBoneNodeNames.Length];
                    sSkinnedMeshRenderer.bones = new Transform[strBoneNodeNames.Length];
                    float[] fGlbTranslation = new float[3 * strBoneNodeNames.Length];
                    Marshal.Copy(sFBXWeight.fGlbTranslation, fGlbTranslation, 0, 3 * strBoneNodeNames.Length);
                    float[] fGlbRotation = new float[4 * strBoneNodeNames.Length];
                    Marshal.Copy(sFBXWeight.fGlbRotation, fGlbRotation, 0, 4 * strBoneNodeNames.Length);
                    float[] fGlbScale = new float[3 * strBoneNodeNames.Length];
                    Marshal.Copy(sFBXWeight.fGlbScale, fGlbScale, 0, 3 * strBoneNodeNames.Length);
                    for (int i = 0; i < strBoneNodeNames.Length; i++)
                    {
                        /*
                        Matrix4x4 matBindPose = new Matrix4x4();
                        matBindPose.m00 = matBonePose[(i * 16) + 0];
                        matBindPose.m01 = matBonePose[(i * 16) + 1];
                        matBindPose.m02 = matBonePose[(i * 16) + 2];
                        matBindPose.m03 = matBonePose[(i * 16) + 3];
                        matBindPose.m10 = matBonePose[(i * 16) + 4];
                        matBindPose.m11 = matBonePose[(i * 16) + 5];
                        matBindPose.m12 = matBonePose[(i * 16) + 6];
                        matBindPose.m13 = matBonePose[(i * 16) + 7];
                        matBindPose.m20 = matBonePose[(i * 16) + 8];
                        matBindPose.m21 = matBonePose[(i * 16) + 9];
                        matBindPose.m22 = matBonePose[(i * 16) + 10];
                        matBindPose.m23 = matBonePose[(i * 16) + 11];
                        matBindPose.m30 = matBonePose[(i * 16) + 12] * fGlobalScale;
                        matBindPose.m31 = matBonePose[(i * 16) + 13] * fGlobalScale;
                        matBindPose.m32 = matBonePose[(i * 16) + 14] * fGlobalScale;
                        matBindPose.m33 = matBonePose[(i * 16) + 15];
                        */
                        Transform bone = goTopAttachNode.transform.FindDeep(strBoneNodeNames[i]).transform;
                        bone.position = new Vector3(-fGlbTranslation[(i * 3) + 0] * fGlobalScale, fGlbTranslation[(i * 3) + 1] * fGlobalScale, fGlbTranslation[(i * 3) + 2] * fGlobalScale);
                        bone.rotation = new Quaternion(-fGlbRotation[(i * 4) + 0], fGlbRotation[(i * 4) + 1], fGlbRotation[(i * 4) + 2], -fGlbRotation[(i * 4) + 3]);
                        bone.localScale = new Vector3(fGlbScale[(i * 3) + 0], fGlbScale[(i * 3) + 1], fGlbScale[(i * 3) + 2]);
                        bones[i] = bone;
                        bindposes[i] = bones[i].worldToLocalMatrix;
                    }
                    //sSkinnedMeshRenderer.rootBone = goNode.transform;
                    sSkinnedMeshRenderer.bones = bones;
                    sSkinnedMeshRenderer.sharedMesh = sMesh;
                    sSkinnedMeshRenderer.sharedMesh.bindposes = bindposes;
                    //sSkinnedMeshRenderer.sharedMesh.RecalculateNormals();
                    //sSkinnedMeshRenderer.sharedMesh.RecalculateBounds();
                }
            }

            // Set Material
            SetMaterial(goNode);
        }
    }
Ejemplo n.º 6
0
        private FBXNode CreateFbxMesh(MESkeletalMesh mesh, string mname, FBXScene pScene, float exportScale = 1.0f)
        {
            MESkeletalMesh.LODModelStruct lod = mesh.LODModels[0];
            FBXMesh fbxMesh   = FBXMesh.Create(pScene, mname);
            FBXNode lMeshNode = FBXNode.Create(pScene, mname);

            lMeshNode.SetNodeAttribute(fbxMesh);
            FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent();

            lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial();

            lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon);
            lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect);
            fbxMesh.InitControlPoints(lod.NumVertices);

            // init UV maps
            FBXGeometryElementUV[] UVs = new FBXGeometryElementUV[lod.Sections.Count];
            for (int s = 0; s < lod.Sections.Count; s++)
            {
                string matName = GetMatName(mesh, lod, s);
                UVs[s] = fbxMesh.CreateElementUV(matName);
                UVs[s].SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            }

            // vertices
            for (int j = 0; j < lod.VertexBufferGPUSkin.Vertices.Count; j++)
            {
                var        vertex   = lod.VertexBufferGPUSkin.Vertices[j];
                FBXVector4 position = new FBXVector4(vertex.Position.X * exportScale, -vertex.Position.Y * exportScale, vertex.Position.Z * exportScale, 0);
                FBXVector4 normal   = new FBXVector4(vertex.TangentX, 0, vertex.TangentZ, 0);
                fbxMesh.SetControlPoint(j, position);
                lGeometryElementTangent.Add(normal);

                // uvs
                for (int s = 0; s < lod.Sections.Count; s++)
                {
                    var sectionVerts = GetSectionVertices(mesh, 0, s);
                    if (sectionVerts.Contains(j))
                    {
                        FBXVector4 texCoords = new FBXVector4(vertex.U, 1 - vertex.V, 0, 0);
                        UVs[s].Add(texCoords);
                    }
                    else
                    {
                        UVs[s].Add(new FBXVector4(0, 0, 0, 0));
                    }
                }
            }

            // faces & mats
            for (int s = 0; s < lod.Sections.Count; s++)
            {
                int chunkId = lod.Sections[s].ChunkIndex;
                var chunk   = lod.Chunks[chunkId];
                // mat
                string matName = GetMatName(mesh, lod, s);
                lMeshNode.AddMaterial(pScene, matName);
                // faces
                for (int j = 0; j < lod.Sections[s].NumTriangles; j++)
                {
                    int baseI = lod.Sections[s].BaseIndex;
                    fbxMesh.BeginPolygon(s);
                    fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3]);
                    fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3 + 1]);
                    fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3 + 2]);
                    fbxMesh.EndPolygon();
                }
            }
            return(lMeshNode);
        }
Ejemplo n.º 7
0
        private void ExportShape(FBXScene fbxScene, FBXNode parentNode, CSGShape shape)
        {
            if (shape.RepresentativeEntityType == CSGEntityType.CSGEShape && shape.ShapeType == CSGShapeType.CSGShapeStandard && shape.GetFaceCount() > 0)
            {
                Dictionary <long, int> fbxPointIdList = new Dictionary <long, int>();
                List <CSGVectorLong>   fbxPointList   = new List <CSGVectorLong>();

                CSGVector[]           pointList                  = null;
                int                   pointListCount             = 0;
                CSGVector[]           normalList                 = null;
                int                   normalListCount            = 0;
                CSGUV[]               textureCoordinateList      = null;
                int                   textureCoordinateListCount = 0;
                CSGMaterialFaceList[] materialFaceList           = null;
                int                   materialFaceListCount      = 0;
                shape.GetGeometryMaterialSorted(
                    true,
                    false,
                    true,
                    ref pointList,
                    ref pointListCount,
                    ref normalList,
                    ref normalListCount,
                    ref textureCoordinateList,
                    ref textureCoordinateListCount,
                    ref materialFaceList,
                    ref materialFaceListCount);

                foreach (var material in materialFaceList)
                {
                    this.ExportMaterial(fbxScene, parentNode, material.Material);
                    foreach (var face in material.FaceList)
                    {
                        foreach (var facePoint in face.PointList)
                        {
                            long          fbxPointKey = facePoint.PointID << 42 | facePoint.NormalID << 21 | facePoint.TextureCoordinateListID[0];
                            CSGVectorLong fbxPoint;
                            if (fbxPointIdList.TryGetValue(fbxPointKey, out int fbxPointId))
                            {
                                fbxPoint = fbxPointList[fbxPointId];
                            }
                            else
                            {
                                fbxPoint = new CSGVectorLong()
                                {
                                    X = facePoint.PointID, Y = facePoint.NormalID, Z = facePoint.TextureCoordinateListID[0]
                                };
                                fbxPointId = fbxPointList.Count;

                                fbxPointList.Add(fbxPoint);

                                fbxPointIdList.Add(fbxPointKey, fbxPointId);
                            }
                        }
                    }
                }

                string shapeName = this.GetUniqueName(shape.Name, "shape");

                FBXMesh fbxMesh = FBXMesh.Create(fbxScene, shapeName);
                parentNode.AddNodeAttribute(fbxMesh);

                fbxMesh.InitControlPoints(fbxPointIdList.Count);
                fbxMesh.InitMaterialIndices(ArcManagedFBX.Types.EMappingMode.eByPolygon);
                fbxMesh.InitNormals(fbxPointIdList.Count);
                fbxMesh.InitTextureUV(0);
                fbxMesh.InitTextureUVIndices(ArcManagedFBX.Types.EMappingMode.eByControlPoint);

                int id = 0;
                foreach (var point in fbxPointList)
                {
                    FBXVector controlPoint = new FBXVector(pointList[point.X].X, pointList[point.X].Y, -pointList[point.X].Z);
                    fbxMesh.SetControlPointAt(controlPoint, id);

                    FBXVector normal = new FBXVector(normalList[point.Y].X, normalList[point.Y].Y, -normalList[point.Y].Z);
                    fbxMesh.SetControlPointNormalAt(normal, id);

                    ConvertTextureCoordinate(textureCoordinateList, point);

                    fbxMesh.AddTextureUV(new FBXVector2(textureCoordinateList[point.Z].U, textureCoordinateList[point.Z].V));

                    id++;
                }

                int materialId = 0;
                foreach (var material in materialFaceList)
                {
                    foreach (var face in material.FaceList)
                    {
                        fbxMesh.BeginPolygon(materialId, -1, -1, true);
                        foreach (var facePoint in face.PointList.Reverse())
                        {
                            long fbxPointKey = facePoint.PointID << 42 | facePoint.NormalID << 21 | facePoint.TextureCoordinateListID[0];
                            if (fbxPointIdList.TryGetValue(fbxPointKey, out int fbxPointId))
                            {
                                fbxMesh.AddPolygon(fbxPointId, fbxPointId);
                            }
                            else
                            {
                                // should never happen
                                Debug.WriteLine("what to do for the impossible?");
                                fbxMesh.AddPolygon(0, 0);
                            }
                        }

                        fbxMesh.EndPolygon();
                    }

                    materialId++;
                }
            }
        }
Ejemplo n.º 8
0
        private FBXNode CreateFbxMesh(MeshLOD lod, FBXScene pScene)
        {
            FBXMesh fbxMesh   = FBXMesh.Create(pScene, lod.shortName);
            FBXNode lMeshNode = FBXNode.Create(pScene, lod.shortName);

            lMeshNode.SetNodeAttribute(fbxMesh);
            FBXGeometryElementNormal lGeometryElementNormal = fbxMesh.CreateElementNormal();

            lGeometryElementNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementBinormal lGeometryElementBiNormal = fbxMesh.CreateElementBinormal();

            lGeometryElementBiNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent();

            lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial();

            lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon);
            lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect);
            int verticesCount = lod.GetLODTotalVertCount();

            fbxMesh.InitControlPoints(verticesCount);
            List <FBXGeometryElementUV[]> UVs = new List <FBXGeometryElementUV[]>();

            for (int i = 0; i < lod.sections.Count; i++)
            {
                UVs.Add(new FBXGeometryElementUV[Vertex.UV_SLOTS]);
            }
            int VertexOffset = 0;

            for (int i = 0; i < lod.sections.Count; i++)
            {
                MeshLodSection section = lod.sections[i];
                for (int j = 0; j < section.vertices.Count; j++)
                {
                    FBXVector4 position = new FBXVector4(section.vertices[j].position.members[0] * exportScale, section.vertices[j].position.members[1] * exportScale, section.vertices[j].position.members[2] * exportScale, 0);
                    FBXVector4 normal   = new FBXVector4(section.vertices[j].normals.members[0], section.vertices[j].normals.members[1], section.vertices[j].normals.members[2], section.vertices[j].normals.members[3]);
                    fbxMesh.SetControlPoint(VertexOffset + j, position);
                    lGeometryElementNormal.Add(normal);

                    // adding a check on bitangent and tangent as some meshes don't have them...
                    if (section.vertices[j].biTangents.members.Length == 4)
                    {
                        FBXVector4 bitangent = new FBXVector4(section.vertices[j].biTangents.members[0], section.vertices[j].biTangents.members[1], section.vertices[j].biTangents.members[2], section.vertices[j].biTangents.members[3]);
                        lGeometryElementBiNormal.Add(bitangent);
                    }
                    if (section.vertices[j].tangents.members.Length == 4)
                    {
                        FBXVector4 tangent = new FBXVector4(section.vertices[j].tangents.members[0], section.vertices[j].tangents.members[1], section.vertices[j].tangents.members[2], section.vertices[j].tangents.members[3]);
                        lGeometryElementTangent.Add(tangent);
                    }

                    // multiple UVs management
                    for (int uvInd = 0; uvInd < Vertex.UV_SLOTS; uvInd++)
                    {
                        if (section.vertices[j].texCoords[uvInd] != null)
                        {
                            FBXVector4 texCoords = new FBXVector4(section.vertices[j].texCoords[uvInd].members[0], (-section.vertices[j].texCoords[uvInd].members[1] + 1), 0, 0);
                            if (UVs[i][uvInd] == null)
                            {
                                // if the UV layer does not already exist, we create it...
                                UVs[i][uvInd] = fbxMesh.CreateElementUV(section.matName + "_" + uvInd);
                                UVs[i][uvInd].SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
                                UVs[i][uvInd].SetReferenceMode(FBXWrapper.ReferenceMode.eDirect);

                                // ... and fill it with empty vectors for all previous sections vertices.
                                for (int p = 0; p < VertexOffset + j; p++)
                                {
                                    UVs[i][uvInd].Add(new FBXVector4(0, 0, 0, 0));
                                }
                            }
                            // and now we can add the tex coord of the current vertex we're treating.
                            UVs[i][uvInd].Add(texCoords);
                        }
                    }

                    // since we use direct reference mode for UV, every vertices in the mesh must be present in every UV layer
                    // so for every UV layer created for previous section, we had an empty vector for this vertex.
                    UVs.Where((o, oi) => oi != i).ToList().ForEach(suv =>
                    {
                        for (int subuv = 0; subuv < Vertex.UV_SLOTS; subuv++)
                        {
                            if (suv[subuv] != null)
                            {
                                suv[subuv].Add(new FBXVector4(0, 0, 0, 0));
                            }
                        }
                    }
                                                                   );
                }
                for (int j = 0; j < section.indicies.Count; j++)
                {
                    if (j % 3 == 0)
                    {
                        fbxMesh.EndPolygon();
                        fbxMesh.BeginPolygon(i);
                    }
                    fbxMesh.AddPolygon(VertexOffset + section.indicies[j]);
                }
                fbxMesh.EndPolygon();
                VertexOffset = VertexOffset + section.vertices.Count;
                lMeshNode.AddMaterial(pScene, section.matName);
            }
            return(lMeshNode);
        }
    void ImportSetMesh(string strNodeName, GameObject goNode, GameObject goTopAttachNode, bool bDirectControlPointsMode)
    {
        // Get Mesh
        IntPtr pFBXGetMesh = FBXImporterGetMesh(strNodeName, bInDirectControlPointsMode, bInNormalSmoothing);

        if (pFBXGetMesh != IntPtr.Zero)
        {
            FBXMesh sFBXMesh = new FBXMesh();
            IntPtr  pFBXMesh = Marshal.AllocHGlobal(Marshal.SizeOf(sFBXMesh));
            try
            {
                sFBXMesh = (FBXMesh)Marshal.PtrToStructure(pFBXGetMesh, typeof(FBXMesh));
            }
            finally
            {
                Marshal.FreeHGlobal(pFBXMesh);
            }
            if (bDirectControlPointsMode)
            {
                sFBXMesh.numVertexs = sFBXMesh.numVertexs / 3;
                sFBXMesh.numNormals = sFBXMesh.numNormals / 3;
                sFBXMesh.numUVs     = sFBXMesh.numUVs / 3;
            }

            // Vertex
            float[] fVertexs = new float[sFBXMesh.numVertexs * 3];
            Marshal.Copy(sFBXMesh.fVertexs, fVertexs, 0, sFBXMesh.numVertexs * 3);
            Vector3[] vecVertexs = new Vector3[sFBXMesh.numVertexs];
            int       j          = 0;
            for (int i = 0; i < sFBXMesh.numVertexs; i++)
            {
                vecVertexs[i].x = -fVertexs[j] * fGlobalScale;
                j++;
                vecVertexs[i].y = fVertexs[j] * fGlobalScale;
                j++;
                vecVertexs[i].z = fVertexs[j] * fGlobalScale;
                j++;
            }

            // Normal
            float[] fNormals = new float[sFBXMesh.numNormals * 3];
            Marshal.Copy(sFBXMesh.fNormals, fNormals, 0, sFBXMesh.numNormals * 3);
            Vector3[] vecNormals = new Vector3[sFBXMesh.numNormals];
            j = 0;
            for (int i = 0; i < sFBXMesh.numNormals; i++)
            {
                vecNormals[i].x = -fNormals[j];
                j++;
                vecNormals[i].y = fNormals[j];
                j++;
                vecNormals[i].z = fNormals[j];
                j++;
            }

            // UV
            float[] fUVs = new float[sFBXMesh.numUVs * 2];
            Marshal.Copy(sFBXMesh.fUVs, fUVs, 0, sFBXMesh.numUVs * 2);
            Vector2[] vecUVs = new Vector2[sFBXMesh.numUVs];
            j = 0;
            for (int i = 0; i < sFBXMesh.numUVs; i++)
            {
                vecUVs[i].x = fUVs[j];
                j++;
                vecUVs[i].y = fUVs[j];
                j++;
            }

            // Polygon (MaterialID)
            int[] iPolygonMatIDs = new int[sFBXMesh.numPolygonMatID];
            Marshal.Copy(sFBXMesh.iPolygonMatIDs, iPolygonMatIDs, 0, sFBXMesh.numPolygonMatID);
            int   numPolygonIndex = sFBXMesh.numPolygonIndex;
            int[] iPolygonIndexs  = new int[numPolygonIndex];
            Marshal.Copy(sFBXMesh.iPolygonIndexs, iPolygonIndexs, 0, numPolygonIndex);
            if (bDirectControlPointsMode)
            {
                sFBXMesh.numPolygonMatID = sFBXMesh.numPolygonMatID / 3;
            }

            // Set Mesh
            goNode.AddComponent <MeshRenderer>();
            goNode.AddComponent <MeshFilter>();
            Mesh sMesh = new Mesh();
            sMesh.name = goNode.name;
            goNode.GetComponent <MeshFilter>().mesh = sMesh;
            sMesh.Clear();
            sMesh.vertices     = vecVertexs;
            sMesh.normals      = vecNormals;
            sMesh.uv           = vecUVs;
            sMesh.subMeshCount = sFBXMesh.numMatID;
            List <List <int> > listListMatIDIndeices = new List <List <int> >();
            for (int i = 0; i < sFBXMesh.numMatID; i++)
            {
                List <int> iListMatIDIndeices = new List <int>();
                listListMatIDIndeices.Add(iListMatIDIndeices);
            }

            // Polygon (Material Index)
            if (bDirectControlPointsMode)
            {
                j = 0;
                for (int i = 0; i < sFBXMesh.numPolygonMatID; i++)
                {
                    int iMatID = iPolygonMatIDs[i];
                    if (iMatID < listListMatIDIndeices.Count)
                    {
                        listListMatIDIndeices[iMatID].Add(iPolygonIndexs[j + 0]);
                        listListMatIDIndeices[iMatID].Add(iPolygonIndexs[j + 2]);
                        listListMatIDIndeices[iMatID].Add(iPolygonIndexs[j + 1]);
                        j = j + 3;
                    }
                }
            }
            else
            {
                j = 0;
                for (int i = 0; i < sFBXMesh.numPolygonMatID; i++)
                {
                    int iMatID = iPolygonMatIDs[i];
                    if (iMatID < listListMatIDIndeices.Count)
                    {
                        listListMatIDIndeices[iMatID].Add(j + 0);
                        listListMatIDIndeices[iMatID].Add(j + 2);
                        listListMatIDIndeices[iMatID].Add(j + 1);
                        j = j + 3;
                    }
                }
            }

            // Triangles (Material Index)
            j = 0;
            for (int i = 0; i < sFBXMesh.numMatID; i++)
            {
                int[] iMatIDIndeices = listListMatIDIndeices[i].ToArray();
                //if (iMatIDIndeices.Length > 0)
                {
                    sMesh.SetTriangles(iMatIDIndeices, j);
                    j++;
                }
            }

            // Get Weight
            IntPtr pFBXGetWeight = FBXImporterGetWeight(strNodeName, iPolygonIndexs, numPolygonIndex, bInDirectControlPointsMode);
            if (pFBXGetWeight != IntPtr.Zero)
            {
                FBXWeight sFBXWeight = new FBXWeight();
                IntPtr    pFBXWeight = Marshal.AllocHGlobal(Marshal.SizeOf(sFBXWeight));
                try
                {
                    sFBXWeight = (FBXWeight)Marshal.PtrToStructure(pFBXGetWeight, typeof(FBXWeight));
                }
                finally
                {
                    Marshal.FreeHGlobal(pFBXWeight);
                }
                if (bDirectControlPointsMode)
                {
                    sFBXWeight.iBoneWeightCount = sFBXWeight.iBoneWeightCount / 3;
                }

                // Weight (Bone)
                int[] iBoneID = new int[sFBXWeight.iBoneWeightCount * 4];
                Marshal.Copy(sFBXWeight.iBoneID, iBoneID, 0, sFBXWeight.iBoneWeightCount * 4);
                float[] fBoneWeight = new float[sFBXWeight.iBoneWeightCount * 4];
                Marshal.Copy(sFBXWeight.fBoneWeight, fBoneWeight, 0, sFBXWeight.iBoneWeightCount * 4);
                BoneWeight[] boneWeights = new BoneWeight[sFBXWeight.iBoneWeightCount];
                for (int i = 0; i < sFBXWeight.iBoneWeightCount; i++)
                {
                    BoneWeight boneWeight = new BoneWeight();
                    boneWeight.boneIndex0 = iBoneID[(i * 4) + 0];
                    boneWeight.boneIndex1 = iBoneID[(i * 4) + 1];
                    boneWeight.boneIndex2 = iBoneID[(i * 4) + 2];
                    boneWeight.boneIndex3 = iBoneID[(i * 4) + 3];
                    boneWeight.weight0    = fBoneWeight[(i * 4) + 0];
                    boneWeight.weight1    = fBoneWeight[(i * 4) + 1];
                    boneWeight.weight2    = fBoneWeight[(i * 4) + 2];
                    boneWeight.weight3    = fBoneWeight[(i * 4) + 3];
                    boneWeights[i]        = boneWeight;
                }
                sMesh.boneWeights = boneWeights;

                // Bind Pose (Bone)
                SkinnedMeshRenderer sSkinnedMeshRenderer = goNode.AddComponent <SkinnedMeshRenderer>();
                string strBoneName = Marshal.PtrToStringAnsi(sFBXWeight.strBoneNodeNames).ToString();
                if (strBoneName != "")
                {
                    string[] strBoneNodeNames = strBoneName.Split(',');
                    //float[] matBonePose = new float[strBoneNodeNames.Length * 16];
                    //Marshal.Copy(sFBXWeight.matBonePose, matBonePose, 0, strBoneNodeNames.Length * 16);
                    Matrix4x4[] bindposes = new Matrix4x4[strBoneNodeNames.Length];
                    Transform[] bones     = new Transform[strBoneNodeNames.Length];
                    sSkinnedMeshRenderer.bones = new Transform[strBoneNodeNames.Length];
                    float[] fGlbTranslation = new float[3 * strBoneNodeNames.Length];
                    Marshal.Copy(sFBXWeight.fGlbTranslation, fGlbTranslation, 0, 3 * strBoneNodeNames.Length);
                    float[] fGlbRotation = new float[4 * strBoneNodeNames.Length];
                    Marshal.Copy(sFBXWeight.fGlbRotation, fGlbRotation, 0, 4 * strBoneNodeNames.Length);
                    float[] fGlbScale = new float[3 * strBoneNodeNames.Length];
                    Marshal.Copy(sFBXWeight.fGlbScale, fGlbScale, 0, 3 * strBoneNodeNames.Length);
                    for (int i = 0; i < strBoneNodeNames.Length; i++)
                    {
                        /*
                         * Matrix4x4 matBindPose = new Matrix4x4();
                         * matBindPose.m00 = matBonePose[(i * 16) + 0];
                         * matBindPose.m01 = matBonePose[(i * 16) + 1];
                         * matBindPose.m02 = matBonePose[(i * 16) + 2];
                         * matBindPose.m03 = matBonePose[(i * 16) + 3];
                         * matBindPose.m10 = matBonePose[(i * 16) + 4];
                         * matBindPose.m11 = matBonePose[(i * 16) + 5];
                         * matBindPose.m12 = matBonePose[(i * 16) + 6];
                         * matBindPose.m13 = matBonePose[(i * 16) + 7];
                         * matBindPose.m20 = matBonePose[(i * 16) + 8];
                         * matBindPose.m21 = matBonePose[(i * 16) + 9];
                         * matBindPose.m22 = matBonePose[(i * 16) + 10];
                         * matBindPose.m23 = matBonePose[(i * 16) + 11];
                         * matBindPose.m30 = matBonePose[(i * 16) + 12] * fGlobalScale;
                         * matBindPose.m31 = matBonePose[(i * 16) + 13] * fGlobalScale;
                         * matBindPose.m32 = matBonePose[(i * 16) + 14] * fGlobalScale;
                         * matBindPose.m33 = matBonePose[(i * 16) + 15];
                         */
                        Transform bone = goTopAttachNode.transform.FindDeep(strBoneNodeNames[i]).transform;
                        bone.position   = new Vector3(-fGlbTranslation[(i * 3) + 0] * fGlobalScale, fGlbTranslation[(i * 3) + 1] * fGlobalScale, fGlbTranslation[(i * 3) + 2] * fGlobalScale);
                        bone.rotation   = new Quaternion(-fGlbRotation[(i * 4) + 0], fGlbRotation[(i * 4) + 1], fGlbRotation[(i * 4) + 2], -fGlbRotation[(i * 4) + 3]);
                        bone.localScale = new Vector3(fGlbScale[(i * 3) + 0], fGlbScale[(i * 3) + 1], fGlbScale[(i * 3) + 2]);
                        bones[i]        = bone;
                        bindposes[i]    = bones[i].worldToLocalMatrix;
                    }
                    //sSkinnedMeshRenderer.rootBone = goNode.transform;
                    sSkinnedMeshRenderer.bones                = bones;
                    sSkinnedMeshRenderer.sharedMesh           = sMesh;
                    sSkinnedMeshRenderer.sharedMesh.bindposes = bindposes;
                    //sSkinnedMeshRenderer.sharedMesh.RecalculateNormals();
                    //sSkinnedMeshRenderer.sharedMesh.RecalculateBounds();
                }
            }

            // Set Material
            SetMaterial(goNode);
        }
    }
Ejemplo n.º 10
0
        private FBXNode CreateFbxMesh(MeshLOD lod, FBXScene pScene)
        {
            FBXMesh fbxMesh   = FBXMesh.Create(pScene, lod.shortName);
            FBXNode lMeshNode = FBXNode.Create(pScene, lod.shortName);

            lMeshNode.SetNodeAttribute(fbxMesh);
            FBXGeometryElementNormal lGeometryElementNormal = fbxMesh.CreateElementNormal();

            lGeometryElementNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementBinormal lGeometryElementBiNormal = fbxMesh.CreateElementBinormal();

            lGeometryElementBiNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent();

            lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
            FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial();

            lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon);
            lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect);
            int verticesCount = lod.GetLODTotalVertCount();

            fbxMesh.InitControlPoints(verticesCount);
            List <FBXGeometryElementUV> UVs = new List <FBXGeometryElementUV>();

            for (int i = 0; i < lod.sections.Count; i++)
            {
                MeshLodSection       section           = lod.sections[i];
                FBXGeometryElementUV lUVDiffuseElement = fbxMesh.CreateElementUV(section.matName);
                lUVDiffuseElement.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint);
                lUVDiffuseElement.SetReferenceMode(FBXWrapper.ReferenceMode.eDirect);
                UVs.Add(lUVDiffuseElement);
            }
            int VertexOffset = 0;

            for (int i = 0; i < lod.sections.Count; i++)
            {
                MeshLodSection section = lod.sections[i];
                for (int j = 0; j < section.vertices.Count; j++)
                {
                    FBXVector4 position   = new FBXVector4(section.vertices[j].position.members[0] * exportScale, section.vertices[j].position.members[1] * exportScale, section.vertices[j].position.members[2] * exportScale, 0);
                    FBXVector4 normal     = new FBXVector4(section.vertices[j].normals.members[0], section.vertices[j].normals.members[1], section.vertices[j].normals.members[2], section.vertices[j].normals.members[3]);
                    FBXVector4 textCoords = new FBXVector4(section.vertices[j].texCoords.members[0], (-section.vertices[j].texCoords.members[1] + 1), 0, 0);
                    FBXVector4 bitangent  = new FBXVector4(section.vertices[j].biTangents.members[0], section.vertices[j].biTangents.members[1], section.vertices[j].biTangents.members[2], section.vertices[j].biTangents.members[3]);
                    FBXVector4 tangent    = new FBXVector4(section.vertices[j].tangents.members[0], section.vertices[j].tangents.members[1], section.vertices[j].tangents.members[2], section.vertices[j].tangents.members[3]);
                    fbxMesh.SetControlPoint(VertexOffset + j, position);
                    lGeometryElementNormal.Add(normal);
                    lGeometryElementBiNormal.Add(bitangent);
                    lGeometryElementTangent.Add(tangent);
                    int uvI = 0;
                    foreach (FBXGeometryElementUV uv in UVs)
                    {
                        if (uvI == i)
                        {
                            uv.Add(textCoords);
                        }
                        else
                        {
                            uv.Add(new FBXVector4(0, 0, 0, 0));
                        }
                        uvI++;
                    }
                }
                for (int j = 0; j < section.indicies.Count; j++)
                {
                    if (j % 3 == 0)
                    {
                        fbxMesh.EndPolygon();
                        fbxMesh.BeginPolygon(i);
                    }
                    fbxMesh.AddPolygon(VertexOffset + section.indicies[j]);
                }
                fbxMesh.EndPolygon();
                VertexOffset = VertexOffset + section.vertices.Count;
                lMeshNode.AddMaterial(pScene, section.matName);
            }
            return(lMeshNode);
        }