private Submesh3D ImportSubmesh(FbxSubmesh meshAttribute, FbxNode node) { var sm = new Submesh3D { Mesh = new Mesh <Mesh3D.Vertex> { Vertices = meshAttribute.Vertices, Indices = meshAttribute.Indices.Select(index => checked ((ushort)index)).ToArray(), AttributeLocations = new[] { ShaderPrograms.Attributes.Pos1, ShaderPrograms.Attributes.Color1, ShaderPrograms.Attributes.UV1, ShaderPrograms.Attributes.BlendIndices, ShaderPrograms.Attributes.BlendWeights, ShaderPrograms.Attributes.Normal, ShaderPrograms.Attributes.Tangent } }, Material = meshAttribute.MaterialIndex != -1 && node.Materials != null ? GetOrCreateLimeMaterial(node.Materials[meshAttribute.MaterialIndex]) : FbxMaterial.Default }; MeshUtils.RemoveDuplicates(sm.Mesh); if (meshAttribute.Bones.Length > 0) { foreach (var bone in meshAttribute.Bones) { sm.BoneNames.Add(bone.Name); sm.BoneBindPoses.Add(bone.Offset); } } return(sm); }
private static List <FbxSubmesh> ImportSubmeshes(IntPtr ptr) { var list = new List <FbxSubmesh>(); var mesh = FbxNodeGetMeshAttribute(ptr, WindingOrder.CW, true); var indices = mesh.Vertices.ToStruct <SizedArray>().GetData <int>(); var controlPoints = mesh.Points.ToStruct <SizedArray>().GetData <Vec3>(); var weights = mesh.Weigths.ToStruct <SizedArray>().GetData <WeightData>(); var boneData = mesh.Bones.ToStruct <SizedArray>().GetData <BoneData>(); var colorsContainer = mesh.Colors.ToStruct <Element>(); var normalsContainer = mesh.Normals.ToStruct <Element>(); var uvContainer = mesh.UV.ToStruct <Element>(); var colors = colorsContainer.GetData <Vec4>(); var normals = normalsContainer.GetData <Vec3>(); var uv = uvContainer.GetData <Vec2>(); var size = ushort.MaxValue; var count = indices.Length / size; var bones = new FbxBone[boneData.Length]; for (var i = 0; i < boneData.Length; i++) { bones[i] = new FbxBone { Name = boneData[i].Name, Offset = boneData[i].OffsetMatrix.ToStruct <Mat4x4>().ToLime() }; } for (var i = 0; i <= count; i++) { var newSize = i == count ? indices.Length - (size * count) : size; var submesh = new FbxSubmesh { MaterialIndex = mesh.MaterialIndex, Indices = new int[newSize], Vertices = new Mesh3D.Vertex[newSize], Normals = new Vector3[newSize], Bones = bones.ToArray(), }; for (var j = 0; j < submesh.Vertices.Length; j++) { var index = i * size + j; var controlPointIndex = indices[index]; var controlPoint = controlPoints[controlPointIndex]; submesh.Indices[j] = j; submesh.Vertices[j].Pos = controlPoint.ToLime(); if (colorsContainer.Size != 0 && colorsContainer.Mode != ReferenceMode.None) { submesh.Vertices[j].Color = colorsContainer.Mode == ReferenceMode.ControlPoint ? colors[controlPointIndex].ToLimeColor() : colors[index].ToLimeColor(); } else { submesh.Vertices[j].Color = Color4.White; } if (normalsContainer.Size != 0 && normalsContainer.Mode != ReferenceMode.None) { submesh.Vertices[j].Normal = normalsContainer.Mode == ReferenceMode.ControlPoint ? normals[controlPointIndex].ToLime() : normals[index].ToLime(); } if (uvContainer.Size != 0 && uvContainer.Mode != ReferenceMode.None) { submesh.Vertices[j].UV1 = normalsContainer.Mode == ReferenceMode.ControlPoint ? uv[controlPointIndex].ToLime() : uv[index].ToLime(); submesh.Vertices[j].UV1.Y = 1 - submesh.Vertices[j].UV1.Y; } if (weights.Length == 0) { continue; } byte idx; float weight; var weightData = weights[controlPointIndex]; for (var k = 0; k < ImportConfig.BoneLimit; k++) { if (weightData.Weights[k] == NoWeight) { continue; } idx = weightData.Indices[k]; weight = weightData.Weights[k]; switch (k) { case 0: submesh.Vertices[j].BlendIndices.Index0 = idx; submesh.Vertices[j].BlendWeights.Weight0 = weight; break; case 1: submesh.Vertices[j].BlendIndices.Index1 = idx; submesh.Vertices[j].BlendWeights.Weight1 = weight; break; case 2: submesh.Vertices[j].BlendIndices.Index2 = idx; submesh.Vertices[j].BlendWeights.Weight2 = weight; break; case 3: submesh.Vertices[j].BlendIndices.Index3 = idx; submesh.Vertices[j].BlendWeights.Weight3 = weight; break; } } } list.Add(submesh); } return(list); }