/// <summary> /// Export the mesh's vertex color using layer 0. /// </summary> /// public void ExportVertexColors(MeshInfo mesh, FbxMesh fbxMesh) { // Set the normals on Layer 0. FbxLayer fbxLayer = fbxMesh.GetLayer(0 /* default layer */); if (fbxLayer == null) { fbxMesh.CreateLayer(); fbxLayer = fbxMesh.GetLayer(0 /* default layer */); } using (var fbxLayerElement = FbxLayerElementVertexColor.Create(fbxMesh, "VertexColors")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); // TODO: normals for each triangle vertex instead of averaged per control point //fbxNormalLayer.SetMappingMode (FbxLayerElement.eByPolygonVertex); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < mesh.VertexColors.Length; n++) { // Converting to Color from Color32, as Color32 stores the colors // as ints between 0-255, while FbxColor and Color // use doubles between 0-1 Color color = mesh.VertexColors [n]; fbxElementArray.Add(new FbxColor(color.r, color.g, color.b, color.a)); } fbxLayer.SetVertexColors(fbxLayerElement); } }
public void TestEquality() { var aIndex = m_fbxMesh.CreateLayer(); var bIndex = m_fbxMesh.CreateLayer(); var a = m_fbxMesh.GetLayer(aIndex); var b = m_fbxMesh.GetLayer(bIndex); var acopy = m_fbxMesh.GetLayer(aIndex); EqualityTester <FbxLayer> .TestEquality(a, b, acopy); }
public void Init() { m_fbxManager = FbxManager.Create(); m_fbxMesh = FbxMesh.Create(m_fbxManager, ""); m_fbxLayer = m_fbxMesh.GetLayer(0); if (m_fbxLayer == null) { m_fbxMesh.CreateLayer(); m_fbxLayer = m_fbxMesh.GetLayer(0 /* default layer */); } }
/// <summary> /// return base layer for mesh /// </summary> /// private FbxLayer GetBaseLayer(FbxMesh fbxMesh) { FbxLayer fbxLayer = fbxMesh.GetLayer(0 /* default layer */); if (fbxLayer == null) { fbxMesh.CreateLayer(); fbxLayer = fbxMesh.GetLayer(0 /* default layer */); } return(fbxLayer); }
/// <summary> /// Export the mesh's UVs using layer 0. /// </summary> public void ExportUVs(MeshInfo mesh, FbxMesh fbxMesh) { // Set the normals on Layer 0. FbxLayer fbxLayer = fbxMesh.GetLayer(0 /* default layer */); if (fbxLayer == null) { fbxMesh.CreateLayer(); fbxLayer = fbxMesh.GetLayer(0 /* default layer */); } using (var fbxLayerElement = FbxLayerElementUV.Create(fbxMesh, "UVSet")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByPolygonVertex); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eIndexToDirect); // set texture coordinates per vertex FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < mesh.UV.Length; n++) { fbxElementArray.Add(new FbxVector2(mesh.UV [n] [0], mesh.UV [n] [1])); } // For each face index, point to a texture uv var unityTriangles = mesh.Triangles; FbxLayerElementArray fbxIndexArray = fbxLayerElement.GetIndexArray(); fbxIndexArray.SetCount(unityTriangles.Length); for (int i = 0, n = unityTriangles.Length; i < n; ++i) { fbxIndexArray.SetAt(i, unityTriangles[i]); } fbxLayer.SetUVs(fbxLayerElement, FbxLayerElement.EType.eTextureDiffuse); } }
protected override FbxScene CreateScene(FbxManager manager) { FbxScene scene = base.CreateScene(manager); // Set the UVs FbxMesh cubeMesh = scene.GetRootNode().GetChild(0).GetMesh(); FbxLayer fbxLayer = cubeMesh.GetLayer(0 /* default layer */); if (fbxLayer == null) { cubeMesh.CreateLayer(); fbxLayer = cubeMesh.GetLayer(0 /* default layer */); } using (var fbxLayerElement = FbxLayerElementUV.Create(cubeMesh, "UVSet")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByPolygonVertex); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eIndexToDirect); // set texture coordinates per vertex FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < 8; n++) { fbxElementArray.Add(new FbxVector2(n % 2, 1)); // TODO: switch to correct values } // For each face index, point to a texture uv FbxLayerElementArray fbxIndexArray = fbxLayerElement.GetIndexArray(); fbxIndexArray.SetCount(24); for (int vertIndex = 0; vertIndex < 24; vertIndex++) { fbxIndexArray.SetAt(vertIndex, vertIndex % 8); // TODO: switch to correct values } fbxLayer.SetUVs(fbxLayerElement, FbxLayerElement.EType.eTextureDiffuse); } // Create the material var fbxMaterial = FbxSurfacePhong.Create(scene, m_materialName); fbxMaterial.Diffuse.Set(new FbxColor(1, 1, 1)); fbxMaterial.Emissive.Set(new FbxColor(0.5, 0.1, 0.2)); fbxMaterial.Ambient.Set(new FbxDouble3(0.3, 0.4, 0)); fbxMaterial.BumpFactor.Set(0.6); fbxMaterial.Specular.Set(new FbxDouble3(0.8, 0.7, 0.9)); // Create and add the texture var fbxMaterialProperty = fbxMaterial.FindProperty(FbxSurfaceMaterial.sDiffuse); Assert.IsNotNull(fbxMaterialProperty); Assert.IsTrue(fbxMaterialProperty.IsValid()); var fbxTexture = FbxFileTexture.Create(fbxMaterial, FbxSurfaceMaterial.sDiffuse + "_Texture"); fbxTexture.SetFileName("/path/to/some/texture.jpg"); fbxTexture.SetTextureUse(FbxTexture.ETextureUse.eStandard); fbxTexture.SetMappingType(FbxTexture.EMappingType.eUV); fbxTexture.ConnectDstProperty(fbxMaterialProperty); scene.GetRootNode().GetChild(0).AddMaterial(fbxMaterial); return(scene); }
protected override FbxScene CreateScene(FbxManager manager) { FbxScene scene = base.CreateScene(manager); // Add normals, binormals, UVs, tangents and vertex colors to the cube FbxMesh cubeMesh = scene.GetRootNode().GetChild(0).GetMesh(); // Add normals /// Set the Normals on Layer 0. FbxLayer fbxLayer = cubeMesh.GetLayer(0 /* default layer */); if (fbxLayer == null) { cubeMesh.CreateLayer(); fbxLayer = cubeMesh.GetLayer(0 /* default layer */); } using (var fbxLayerElement = FbxLayerElementNormal.Create(cubeMesh, "Normals")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); // Assign the normal vectors in the same order the control points were defined FbxVector4[] normals = { normalZPos, normalXPos, normalZNeg, normalXNeg, normalYPos, normalYNeg }; for (int n = 0; n < normals.Length; n++) { for (int i = 0; i < 4; i++) { fbxElementArray.Add(normals [n]); } } fbxLayer.SetNormals(fbxLayerElement); } /// Set the binormals on Layer 0. using (var fbxLayerElement = FbxLayerElementBinormal.Create(cubeMesh, "Binormals")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < cubeMesh.GetControlPointsCount(); n++) { fbxElementArray.Add(new FbxVector4(-1, 0, 1)); // TODO: set to correct values } fbxLayer.SetBinormals(fbxLayerElement); } /// Set the tangents on Layer 0. using (var fbxLayerElement = FbxLayerElementTangent.Create(cubeMesh, "Tangents")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < cubeMesh.GetControlPointsCount(); n++) { fbxElementArray.Add(new FbxVector4(0, -1, 1)); // TODO: set to correct values } fbxLayer.SetTangents(fbxLayerElement); } // set the vertex colors using (var fbxLayerElement = FbxLayerElementVertexColor.Create(cubeMesh, "VertexColors")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); // make each vertex either black or white for (int n = 0; n < cubeMesh.GetControlPointsCount(); n++) { fbxElementArray.Add(new FbxColor(n % 2, n % 2, n % 2)); } fbxLayer.SetVertexColors(fbxLayerElement); } // set the UVs using (var fbxLayerElement = FbxLayerElementUV.Create(cubeMesh, "UVSet")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByPolygonVertex); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eIndexToDirect); // set texture coordinates per vertex FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < 8; n++) { fbxElementArray.Add(new FbxVector2(n % 2, 1)); // TODO: switch to correct values } // For each face index, point to a texture uv FbxLayerElementArray fbxIndexArray = fbxLayerElement.GetIndexArray(); fbxIndexArray.SetCount(24); for (int vertIndex = 0; vertIndex < 24; vertIndex++) { fbxIndexArray.SetAt(vertIndex, vertIndex % 8); // TODO: switch to correct values } fbxLayer.SetUVs(fbxLayerElement, FbxLayerElement.EType.eTextureDiffuse); } return(scene); }
// For use only by FbxExportGlobals. internal static FbxMesh CreateFbxMesh(FbxExportGlobals G, GeometryPool pool, string poolName) { FbxMesh fbxMesh = FbxMesh.Create(G.m_manager, poolName); ExportMesh mesh = new ExportMesh(pool); int nVerts = mesh.m_pool.m_Vertices.Count; fbxMesh.InitControlPoints(nVerts); unsafe { fixed(Vector3 *f = mesh.m_pool.m_Vertices.GetBackingArray()) { Globals.SetControlPoints(fbxMesh, (IntPtr)f); } } List <int> triangles = mesh.m_pool.m_Tris; // Not available in Unity's wrappers // fbxMesh.ReservePolygonCount(triangles.Count / 3); // fbxMesh.ReservePolygonVertexCount(triangles.Count); for (int i = 0; i < triangles.Count; i += 3) { fbxMesh.BeginPolygon(-1 /* Material */, -1 /* Texture */, -1 /* Group */, false /* Legacy */); fbxMesh.AddPolygon(triangles[i]); fbxMesh.AddPolygon(triangles[i + 1]); fbxMesh.AddPolygon(triangles[i + 2]); fbxMesh.EndPolygon(); } FbxLayer layer0 = fbxMesh.GetLayer(0); if (layer0 == null) { fbxMesh.CreateLayer(); layer0 = fbxMesh.GetLayer(0); } var layerElementNormal = FbxLayerElementNormal.Create(fbxMesh, "normals"); layerElementNormal.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); layerElementNormal.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); CopyToFbx(layerElementNormal.GetDirectArray(), mesh.m_pool.m_Normals); layer0.SetNormals(layerElementNormal); var layerElementColor = FbxLayerElementVertexColor.Create(fbxMesh, "color"); layerElementColor.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); layerElementColor.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); CopyToFbx(layerElementColor.GetDirectArray(), mesh.m_linearColor); layer0.SetVertexColors(layerElementColor); var layerElementTangent = FbxLayerElementTangent.Create(fbxMesh, "tangents"); layerElementTangent.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); layerElementTangent.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); CopyToFbx(layerElementTangent.GetDirectArray(), mesh.m_pool.m_Tangents); layer0.SetTangents(layerElementTangent); // Compute and export binormals since Unity's FBX importer won't import the tangents without // them, even though they're not used. var layerElementBinormal = FbxLayerElementBinormal.Create(fbxMesh, "binormals"); layerElementBinormal.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); layerElementBinormal.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); var binormals = mesh.m_pool.m_Tangents .Select((tan, idx) => { var b3 = Vector3.Cross(tan, mesh.m_pool.m_Normals[idx]) * tan.w; return(new Vector4(b3.x, b3.y, b3.z, 1)); }) .ToList(); CopyToFbx(layerElementBinormal.GetDirectArray(), binormals); layer0.SetBinormals(layerElementBinormal); var layerElementMaterial = FbxLayerElementMaterial.Create(fbxMesh, "materials"); layerElementMaterial.SetMappingMode(FbxLayerElement.EMappingMode.eAllSame); layer0.SetMaterials(layerElementMaterial); // Export everything up to the last uvset containing data // even if some intermediate uvsets have no data. // Otherwise Unity will get the uvset numbering wrong on import List <List <Vector2> > uvSets = DemuxTexcoords(mesh.m_pool); for (int i = 0; i < uvSets.Count; i++) { FbxLayer layerN = fbxMesh.GetLayer(i); while (layerN == null) { fbxMesh.CreateLayer(); layerN = fbxMesh.GetLayer(i); } var layerElementUV = FbxLayerElementUV.Create(fbxMesh, String.Format("uv{0}", i)); layerElementUV.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); layerElementUV.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); List <Vector2> uvSet = uvSets[i]; if (uvSet == null) { // Do nothing // Replicates what the old fbx export code did; seems to work fine } else { Debug.Assert(uvSet.Count == nVerts); CopyToFbx(layerElementUV.GetDirectArray(), uvSet); } layerN.SetUVs(layerElementUV, FbxLayerElement.EType.eTextureDiffuse); } return(fbxMesh); }
/// <summary> /// Export the mesh's normals, binormals and tangents using /// layer 0. /// </summary> /// public void ExportNormalsEtc(MeshInfo mesh, FbxMesh fbxMesh) { /// Set the Normals on Layer 0. FbxLayer fbxLayer = fbxMesh.GetLayer(0 /* default layer */); if (fbxLayer == null) { fbxMesh.CreateLayer(); fbxLayer = fbxMesh.GetLayer(0 /* default layer */); } using (var fbxLayerElement = FbxLayerElementNormal.Create(fbxMesh, "Normals")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); // TODO: normals for each triangle vertex instead of averaged per control point //fbxNormalLayer.SetMappingMode (FbxLayerElement.eByPolygonVertex); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < mesh.Normals.Length; n++) { fbxElementArray.Add(new FbxVector4(mesh.Normals [n] [0], mesh.Normals [n] [1], mesh.Normals [n] [2])); } fbxLayer.SetNormals(fbxLayerElement); } /// Set the binormals on Layer 0. using (var fbxLayerElement = FbxLayerElementBinormal.Create(fbxMesh, "Binormals")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); // TODO: normals for each triangle vertex instead of averaged per control point //fbxBinormalLayer.SetMappingMode (FbxLayerElement.eByPolygonVertex); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < mesh.Binormals.Length; n++) { fbxElementArray.Add(new FbxVector4(mesh.Binormals [n] [0], mesh.Binormals [n] [1], mesh.Binormals [n] [2])); } fbxLayer.SetBinormals(fbxLayerElement); } /// Set the tangents on Layer 0. using (var fbxLayerElement = FbxLayerElementTangent.Create(fbxMesh, "Tangents")) { fbxLayerElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint); // TODO: normals for each triangle vertex instead of averaged per control point //fbxBinormalLayer.SetMappingMode (FbxLayerElement.eByPolygonVertex); fbxLayerElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect); // Add one normal per each vertex face index (3 per triangle) FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray(); for (int n = 0; n < mesh.Normals.Length; n++) { fbxElementArray.Add(new FbxVector4(mesh.Tangents [n] [0], mesh.Tangents [n] [1], mesh.Tangents [n] [2])); } fbxLayer.SetTangents(fbxLayerElement); } }