protected override void CheckScene(FbxScene scene) { FbxScene origScene = CreateScene(FbxManager); Assert.IsNotNull(origScene); Assert.IsNotNull(scene); // Retrieve the mesh from each scene FbxMesh origMesh = origScene.GetRootNode().GetChild(0).GetMesh(); FbxMesh importMesh = scene.GetRootNode().GetChild(0).GetMesh(); Assert.IsNotNull(origMesh); Assert.IsNotNull(importMesh); // check that the control points match Assert.AreEqual(origMesh.GetControlPointsCount(), importMesh.GetControlPointsCount()); for (int i = 0; i < origMesh.GetControlPointsCount(); i++) { FbxVector4 origControlPoint = origMesh.GetControlPointAt(i); FbxVector4 importControlPoint = importMesh.GetControlPointAt(i); // Note: Ignoring W as no matter what it is set to it always imports as 0 Assert.AreEqual(origControlPoint.X, importControlPoint.X); Assert.AreEqual(origControlPoint.Y, importControlPoint.Y); Assert.AreEqual(origControlPoint.Z, importControlPoint.Z); } }
Mesh GetOrCreateInstance(FbxMesh fbxMesh) { Mesh mesh; if (m_meshInstances.TryGetValue(fbxMesh, out mesh)) { return(mesh); } // create the unity mesh vertices var nVertices = fbxMesh.GetControlPointsCount(); var unityVertices = new Vector3[nVertices]; for (int i = 0; i < nVertices; ++i) { unityVertices[i] = V3(fbxMesh.GetControlPointAt(i)); } // create the unity mesh triangles. TODO: maybe handle non-triangular faces more intelligently var nPoly = fbxMesh.GetPolygonCount(); var unityTriangles = new List <int>(); for (int polyIndex = 0; polyIndex < nPoly; ++polyIndex) { var polySize = fbxMesh.GetPolygonSize(polyIndex); if (polySize < 3) { // ignore lines and points continue; } // Add the first triangle unityTriangles.Add(fbxMesh.GetPolygonVertex(polyIndex, 0)); unityTriangles.Add(fbxMesh.GetPolygonVertex(polyIndex, 1)); unityTriangles.Add(fbxMesh.GetPolygonVertex(polyIndex, 2)); // If there's more triangles, assume they're a fan around the first vertex. // Not necessarily true, but them's the breaks. for (int i = 3; i < polySize; ++i) { unityTriangles.Add(fbxMesh.GetPolygonVertex(polyIndex, 0)); unityTriangles.Add(fbxMesh.GetPolygonVertex(polyIndex, i - 1)); unityTriangles.Add(fbxMesh.GetPolygonVertex(polyIndex, i)); } } mesh = new Mesh { name = fbxMesh.GetName(), vertices = unityVertices, triangles = unityTriangles.ToArray() }; mesh.RecalculateNormals(); m_meshInstances[fbxMesh] = mesh; return(mesh); }
/// <summary> /// Convert scene's system units but leave scaling unchanged /// </summary> public void ConvertScene(FbxScene fbxScene, FbxSystemUnit toUnits) { // Get scale factor. float scaleFactor = 1.0f; scaleFactor = (float)fbxScene.GetGlobalSettings().GetSystemUnit().GetConversionFactorTo(toUnits); if (scaleFactor.Equals(1.0f)) { return; } // Get root node. FbxNode fbxRootNode = fbxScene.GetRootNode(); // For all the nodes to convert the translations Queue <FbxNode> fbxNodes = new Queue <FbxNode> (); fbxNodes.Enqueue(fbxRootNode); while (fbxNodes.Count > 0) { FbxNode fbxNode = fbxNodes.Dequeue(); // Convert node's translation. FbxDouble3 lclTrs = fbxNode.LclTranslation.Get(); #if UNI_18844 lclTrs *= scaleFactor; lclTrs *= scaleFactor; lclTrs *= scaleFactor; #endif fbxNode.LclTranslation.Set(lclTrs); FbxMesh fbxMesh = fbxNode.GetMesh(); if (fbxMesh != null) { for (int i = 0; i < fbxMesh.GetControlPointsCount(); ++i) { FbxVector4 fbxVector4 = fbxMesh.GetControlPointAt(i); #if UNI_18844 fbxVector4 *= scaleFactor; #endif fbxMesh.SetControlPointAt(fbxVector4, i); } } for (int i = 0; i < fbxNode.GetChildCount(); ++i) { fbxNodes.Enqueue(fbxNode.GetChild(i)); } } }
public void GeometryBase_SetControlPointAt_SetsControlPoint() { // given: var gb = new FbxMesh(""); gb.InitControlPoints(4); // require: Assert.AreEqual(4, gb.GetControlPointsCount()); Assert.AreEqual(new FbxVector4(0, 0, 0, 0), gb.GetControlPointAt(0)); Assert.AreEqual(new FbxVector4(0, 0, 0, 0), gb.GetControlPointAt(1)); Assert.AreEqual(new FbxVector4(0, 0, 0, 0), gb.GetControlPointAt(2)); Assert.AreEqual(new FbxVector4(0, 0, 0, 0), gb.GetControlPointAt(3)); // when: gb.SetControlPointAt(new FbxVector4(1.2, 3.4, 5.6, 7.8), 2); // then: Assert.AreEqual(new FbxVector4(0, 0, 0, 0), gb.GetControlPointAt(0)); Assert.AreEqual(new FbxVector4(0, 0, 0, 0), gb.GetControlPointAt(1)); Assert.AreEqual(new FbxVector4(1.2, 3.4, 5.6, 7.8), gb.GetControlPointAt(2)); Assert.AreEqual(new FbxVector4(0, 0, 0, 0), gb.GetControlPointAt(3)); }
/// <summary> /// Process mesh data and setup MeshFilter component /// </summary> private void ProcessMesh(FbxNode fbxNode, GameObject unityGo) { FbxMesh fbxMesh = fbxNode.GetMesh(); if (fbxMesh == null) { return; } var unityMesh = new Mesh(); // create mesh var unityVertices = new List <Vector3> (); var unityTriangleIndices = new List <int> (); // transfer vertices for (int i = 0; i < fbxMesh.GetControlPointsCount(); ++i) { FbxVector4 fbxVector4 = fbxMesh.GetControlPointAt(i); Debug.Assert(fbxVector4.X <= float.MaxValue && fbxVector4.X >= float.MinValue); Debug.Assert(fbxVector4.Y <= float.MaxValue && fbxVector4.Y >= float.MinValue); Debug.Assert(fbxVector4.Z <= float.MaxValue && fbxVector4.Z >= float.MinValue); unityVertices.Add(new Vector3((float)fbxVector4.X, (float)fbxVector4.Y, (float)fbxVector4.Z)); } // transfer triangles for (int polyIndex = 0; polyIndex < fbxMesh.GetPolygonCount(); ++polyIndex) { int polySize = fbxMesh.GetPolygonSize(polyIndex); // only support triangles Debug.Assert(polySize == 3); for (int polyVertexIndex = 0; polyVertexIndex < polySize; ++polyVertexIndex) { int vertexIndex = fbxMesh.GetPolygonVertex(polyIndex, polyVertexIndex); unityTriangleIndices.Add(vertexIndex); } } unityMesh.vertices = unityVertices.ToArray(); // TODO: // - support Mesh.SetTriangles - multiple materials per mesh // - support Mesh.SetIndices - other topologies e.g. quads unityMesh.triangles = unityTriangleIndices.ToArray(); unityMesh.RecalculateNormals(); var unityMeshFilter = unityGo.AddComponent <MeshFilter> (); unityMeshFilter.sharedMesh = unityMesh; var unityRenderer = unityGo.AddComponent <MeshRenderer> (); { // Assign the default material (hack!) var unityPrimitive = GameObject.CreatePrimitive(PrimitiveType.Quad); var unityMat = unityPrimitive.GetComponent <MeshRenderer> ().sharedMaterial; unityRenderer.sharedMaterial = unityMat; UnityEngine.Object.DestroyImmediate(unityPrimitive); } }