Esempio n. 1
0
            /// <summary>
            /// Process a single UV dataset and return data for configuring a Mesh UV attribute
            /// </summary>
            private Vector2 [] ProcessUVSet(FbxLayerElementUV element,
                                            int [] polygonVertexIndices,
                                            int vertexCount)
            {
                Vector2 [] result = new Vector2 [polygonVertexIndices.Length];

                FbxLayerElement.EReferenceMode referenceMode = element.GetReferenceMode();
                FbxLayerElement.EMappingMode   mappingMode   = element.GetMappingMode();

                // direct or via-index
                bool isDirect = referenceMode == FbxLayerElement.EReferenceMode.eDirect;

                var fbxElementArray = element.GetDirectArray();
                var fbxIndexArray   = isDirect ? null : element.GetIndexArray();

                if (mappingMode == FbxLayerElement.EMappingMode.eByControlPoint)
                {
                    if (fbxElementArray.GetCount() != vertexCount)
                    {
                        Debug.LogError(string.Format("UVSet size ({0}) does not match vertex count {1}",
                                                     fbxElementArray.GetCount(), vertexCount));
                        return(null);
                    }

                    for (int i = 0; i < polygonVertexIndices.Length; i++)
                    {
                        int index = i;
                        if (!isDirect)
                        {
                            index = fbxIndexArray.GetAt(i);
                        }

                        FbxVector2 fbxVector2 = fbxElementArray.GetAt(polygonVertexIndices [index]);
                        Debug.Assert(fbxVector2.X >= float.MinValue && fbxVector2.X <= float.MaxValue);
                        Debug.Assert(fbxVector2.Y >= float.MinValue && fbxVector2.Y <= float.MaxValue);

                        result [i] = new Vector2((float)fbxVector2.X, (float)fbxVector2.Y);

                        // UVs in FBX can contain NaNs, so we set these vertices to (0,0)
                        if (float.IsNaN(result [i] [0]) || float.IsNaN(result [i] [1]))
                        {
                            Debug.LogWarning(string.Format("invalid UV detected at {0}", i));
                            result [i] = Vector2.zero;
                        }
                    }
                }
                else if (mappingMode == FbxLayerElement.EMappingMode.eAllSame)
                {
                    FbxVector2 fbxVector2 = fbxElementArray.GetAt(0);
                    Debug.Assert(fbxVector2.X >= float.MinValue && fbxVector2.X <= float.MaxValue);
                    Debug.Assert(fbxVector2.Y >= float.MinValue && fbxVector2.Y <= float.MaxValue);

                    Vector2 value = new Vector2((float)fbxVector2.X, (float)fbxVector2.Y);
                    for (int i = 0; i < polygonVertexIndices.Length; i++)
                    {
                        result [i] = value;
                    }
                }
                else
                {
                    Debug.LogError("unsupported UV-to-Component mapping mode");
                }

                return(result);
            }
Esempio n. 2
0
        protected override FbxMesh GenerateFbx()
        {
            string meshName = (Souls.meshRoot != null ? Souls.meshRoot.Name : "") + "_Mesh";

            FbxMesh mesh = FbxMesh.Create(Scene, meshName);

            mesh.InitControlPoints(Souls.mesh.Vertices.Count);

            int layerIndex = mesh.CreateLayer();

            FbxLayer layer = mesh.GetLayer(layerIndex);

            FbxLayerContainer layerContainer = FbxLayerContainer.Create(Scene, meshName + "_LayerContainer");

            FbxLayerElementUV uv = FbxLayerElementUV.Create(layerContainer, "Diffuse");

            layer.SetUVs(uv);

            FbxLayerElementNormal normal = FbxLayerElementNormal.Create(layerContainer, "Normal");

            layer.SetNormals(normal);
            normal.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
            normal.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);

            FbxLayerElementBinormal binormal = FbxLayerElementBinormal.Create(layerContainer, "Binormal");

            layer.SetBinormals(binormal);

            FbxLayerElementTangent tangent = FbxLayerElementTangent.Create(layerContainer, "Tangent");

            layer.SetTangents(tangent);
            tangent.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
            tangent.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);

            for (int vertexIndex = 0; vertexIndex < Souls.mesh.Vertices.Count; ++vertexIndex)
            {
                FLVER.Vertex vertex = Souls.mesh.Vertices[vertexIndex];

                Vector3 position = vertex.Position;

                // this fixes vertex positions since otherwise the model is turned inside out
                // and it appears like it holds weapons in the left hand
                position.Z = -position.Z;

                normal.GetDirectArray().Add(vertex.Normal.ToFbxVector4());

                tangent.GetDirectArray().Add(new FbxVector4(vertex.Tangents[0].X, vertex.Tangents[0].Y, vertex.Tangents[0].Z));

                Vector2 uvValue = new Vector2(0);

                if (vertex.UVs.Count > 0)
                {
                    uvValue.X = vertex.UVs[0].X;
                    uvValue.Y = vertex.UVs[0].Y;
                }

                uv.GetDirectArray().Add(uvValue.ToFbxVector2());

                mesh.SetControlPointAt(position.ToFbxVector4(), vertexIndex);
            }

            for (int faceSetIndex = 0; faceSetIndex < Souls.mesh.FaceSets.Count; ++faceSetIndex)
            {
                FLVER2.FaceSet faceSet = Souls.mesh.FaceSets[faceSetIndex];

                if (faceSet.Flags != FLVER2.FaceSet.FSFlags.None)
                {
                    continue;
                }

                for (int faceStartIndex = 0; faceStartIndex < faceSet.Indices.Count; faceStartIndex += 3)
                {
                    mesh.AddCompletePolygon(
                        faceSet.Indices[faceStartIndex],
                        faceSet.Indices[faceStartIndex + 1],
                        faceSet.Indices[faceStartIndex + 2]
                        );
                    //mesh.AddCompletePolygon(
                    //    faceSet.Indices[faceStartIndex + 2],
                    //    faceSet.Indices[faceStartIndex + 1],
                    //    faceSet.Indices[faceStartIndex]
                    //);
                }
            }

            mesh.BuildMeshEdgeArray();

            FbxGeometryConverter converter = new FbxGeometryConverter(Scene.GetFbxManager());

            converter.ComputeEdgeSmoothingFromNormals(mesh);
            converter.ComputePolygonSmoothingFromEdgeSmoothing(mesh);

            return(mesh);
        }