/// <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."); } }
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); }
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(""); }
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); } }
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); }
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++; } } }
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); } }
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); }