public SetIndices ( Array indices, int indicesPerFace ) : bool | ||
indices | Array | Index buffer |
indicesPerFace | int | Indices per face |
return | bool |
private Assimp.Mesh ExtractMeshPartGeometry(int meshIndex, int partIndex) { // create new assimp mesh Assimp.Mesh mesh = new Assimp.Mesh(); // Add support for multiple UV layers var textureCoordinateIndex = 0; mesh.UVComponentCount[textureCoordinateIndex] = 2; // prepare vertex extraction var meshReader = new MeshReader(CacheContext.Version, RenderModel.Geometry.Meshes[meshIndex], RenderModelResourceDefinition); var vertexCompressor = new VertexCompressor(RenderModel.Geometry.Compression[0]); var geometryMesh = RenderModel.Geometry.Meshes[meshIndex]; var geometryPart = geometryMesh.Parts[partIndex]; mesh.MaterialIndex = geometryPart.MaterialIndex; // optimize this part to not load and decompress all mesh vertices everytime var vertices = ReadVertices(meshReader, RenderModelResourceStream); DecompressVertices(vertices, vertexCompressor); // get offset in the list of all vertices for the mesh var vertexOffset = GetPartVertexOffset(meshIndex, partIndex); //vertices = vertices.GetRange(vertexOffset, geometryPart.VertexCount); var indices = ReadIndices(meshReader, geometryPart, RenderModelResourceStream); var int_indices = indices.Select(b => (int)b).ToArray(); var indexCount = indices.Length; if (indexCount == 0) { Console.WriteLine($"Failed to extract mesh, no indices."); return(null); } // set index list, maybe require adjustment for vertex buffer offset mesh.SetIndices(int_indices, 3); // build skeleton for each mesh (meh) // create a list of all the mesh bones available in the scene foreach (var node in RenderModel.Nodes) { Bone bone = new Bone(); bone.Name = CacheContext.GetString(node.Name); bone.OffsetMatrix = new Matrix4x4(); mesh.Bones.Add(bone); } for (int i = vertexOffset; i < vertexOffset + geometryPart.VertexCount; i++) { var vertex = vertices[i]; mesh.Vertices.Add(vertex.Position); if (vertex.Normal != null) { mesh.Normals.Add(vertex.Normal); } if (vertex.TexCoords != null) { mesh.TextureCoordinateChannels[textureCoordinateIndex].Add(vertex.TexCoords); } if (vertex.Tangents != null) { mesh.Tangents.Add(vertex.Tangents); } if (vertex.Binormals != null) { mesh.BiTangents.Add(vertex.Binormals); } if (vertex.Indices != null) { for (int j = 0; j < vertex.Indices.Length; j++) { var index = vertex.Indices[j]; var bone = mesh.Bones[index]; Matrix4x4 inverseTransform = new Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); var currentNode = BoneNodes[index]; while (currentNode != null) { Matrix4x4 inverse = (currentNode.Transform.DeepClone()); inverse.Inverse(); inverseTransform = inverse * inverseTransform; currentNode = currentNode.Parent; } bone.OffsetMatrix = inverseTransform; bone.VertexWeights.Add(new VertexWeight(i - vertexOffset, vertex.Weights[j])); } } // Add skinned mesh support and more } // create faces mesh.Faces.Clear(); GenerateFaces(int_indices, vertexOffset, mesh.Faces); return(mesh); }
private static Assimp.Scene GetPMOScene(Pmo pmo) { Assimp.Scene scene = new Assimp.Scene(); scene.RootNode = new Assimp.Node("root"); // Add materials. List <Material> matList = new List <Material>(); for (int t = 0; t < pmo.header.TextureCount; t++) { Material mat = new Material(); mat.Clear(); mat.Name = pmo.textureInfo[t].TextureName; scene.Materials.Add(mat); } // Add skeleton. List <Node> Skeleton = new List <Node>(); for (int b = 0; b < pmo.skeletonHeader.BoneCount; b++) { Pmo.BoneData bn = pmo.boneList[b]; Assimp.Matrix4x4 mtx = new Assimp.Matrix4x4(); mtx.A1 = bn.Transform.M11; mtx.A2 = bn.Transform.M12; mtx.A3 = bn.Transform.M13; mtx.A4 = bn.Transform.M14; mtx.B1 = bn.Transform.M21; mtx.B2 = bn.Transform.M22; mtx.B3 = bn.Transform.M23; mtx.B4 = bn.Transform.M24; mtx.C1 = bn.Transform.M31; mtx.C2 = bn.Transform.M32; mtx.C3 = bn.Transform.M33; mtx.C4 = bn.Transform.M34; mtx.D1 = bn.Transform.M41; mtx.D2 = bn.Transform.M42; mtx.D3 = bn.Transform.M43; mtx.D4 = bn.Transform.M44; Assimp.Matrix4x4 nd_mtx = mtx; nd_mtx.Transpose(); if (bn.ParentBoneIndex == 0xFFFF) { Node curNode = new Node(bn.JointName); curNode.Transform = nd_mtx; scene.RootNode.Children.Add(curNode); Skeleton.Add(curNode); } else { Node curNode = new Node(bn.JointName, Skeleton[bn.ParentBoneIndex]); nd_mtx.A4 *= 100.0f; nd_mtx.B4 *= 100.0f; nd_mtx.C4 *= 100.0f; curNode.Transform = nd_mtx; Skeleton.Add(curNode); scene.RootNode.FindNode(Skeleton[bn.ParentBoneIndex].Name).Children.Add(curNode); } } // Add meshes. for (int i = 0; i < pmo.Meshes.Count; i++) { Assimp.Mesh mesh = new Assimp.Mesh($"Mesh{i}", Assimp.PrimitiveType.Triangle); Pmo.MeshChunks chunk = pmo.Meshes[i]; // Add vertices, vertex color and normals. for (int j = 0; j < chunk.vertices.Count; j++) { mesh.Vertices.Add(new Assimp.Vector3D( chunk.vertices[j].X * pmo.header.ModelScale * 100.0f, chunk.vertices[j].Y * pmo.header.ModelScale * 100.0f, chunk.vertices[j].Z * pmo.header.ModelScale * 100.0f)); mesh.VertexColorChannels[0].Add(new Color4D(1.0f, 1.0f, 1.0f, 1.0f)); mesh.Normals.Add(new Vector3D()); } mesh.SetIndices(chunk.Indices.ToArray(), 3); mesh.MaterialIndex = chunk.SectionInfo.TextureID; scene.Meshes.Add(mesh); for (int v = 0; v < chunk.vertices.Count; v++) { // Build bone influences. for (int z = 0; z < chunk.SectionInfo_opt1.SectionBoneIndices.Length; z++) { if (chunk.SectionInfo_opt1.SectionBoneIndices[z] != 0xFF) { Pmo.BoneData currentBone = new Pmo.BoneData(); int currentIndex = chunk.SectionInfo_opt1.SectionBoneIndices[z]; currentBone = pmo.boneList[currentIndex]; string boneName = currentBone.JointName; Assimp.Matrix4x4 mtx = new Assimp.Matrix4x4(); mtx.A1 = currentBone.Transform.M11; mtx.A2 = currentBone.Transform.M12; mtx.A3 = currentBone.Transform.M13; mtx.A4 = currentBone.Transform.M14; mtx.B1 = currentBone.Transform.M21; mtx.B2 = currentBone.Transform.M22; mtx.B3 = currentBone.Transform.M23; mtx.B4 = currentBone.Transform.M24; mtx.C1 = currentBone.Transform.M31; mtx.C2 = currentBone.Transform.M32; mtx.C3 = currentBone.Transform.M33; mtx.C4 = currentBone.Transform.M34; mtx.D1 = currentBone.Transform.M41; mtx.D2 = currentBone.Transform.M42; mtx.D3 = currentBone.Transform.M43; mtx.D4 = currentBone.Transform.M44; Matrix3x3 mtx3 = new Matrix3x3(mtx); mtx.Transpose(); mtx.A4 *= 100.0f; mtx.B4 *= 100.0f; mtx.C4 *= 100.0f; mtx3.Transpose(); List <VertexWeight> weight = new List <VertexWeight>(); VertexWeight vW = new VertexWeight(); vW.VertexID = v; float currentWeight = chunk.jointWeights[v].weights[z]; switch (chunk.jointWeights[v].coordFormart) { case Pmo.CoordinateFormat.NO_VERTEX: break; case Pmo.CoordinateFormat.NORMALIZED_8_BITS: currentWeight *= 127.0f; currentWeight /= 128.0f; break; case Pmo.CoordinateFormat.NORMALIZED_16_BITS: currentWeight *= 32767.0f; currentWeight /= 32768.0f; break; case Pmo.CoordinateFormat.FLOAT_32_BITS: break; } vW.Weight = currentWeight; weight.Add(vW); Bone tempBone = scene.Meshes[i].Bones.Find(x => x.Name == boneName); int boneInd = scene.Meshes[i].Bones.FindIndex(0, x => x.Name == boneName); if (tempBone == null) { Bone bone = new Bone(boneName, mtx3, weight.ToArray()); scene.Meshes[i].Bones.Add(bone); } else { scene.Meshes[i].Bones[boneInd].VertexWeights.Add(vW); } } } } } scene.RootNode.MeshIndices.AddRange(Enumerable.Range(0, scene.MeshCount)); return(scene); }
Assimp.Mesh FromUnityMesh(UnityEngine.Mesh mesh, string _name, Transform rootGo, Transform[] bones = null) { UnityEngine.Matrix4x4 world = rootGo.transform.localToWorldMatrix; Assimp.Mesh assimpMesh = new Assimp.Mesh(_name, Assimp.PrimitiveType.Triangle); foreach (Vector3 v in mesh.vertices) { Vector3 vW = world.MultiplyPoint3x4(v); assimpMesh.Vertices.Add(new Vector3D(vW.x, vW.y, vW.z)); } foreach (Vector3 n in mesh.normals) { Vector3 nW = world.MultiplyPoint3x4(n); assimpMesh.Normals.Add(new Vector3D(nW.x, nW.y, nW.z)); } foreach (Vector2 u in mesh.uv) { assimpMesh.TextureCoordinateChannels[0].Add(new Vector3D(u.x, 1f - u.y, 0)); } if (mesh.uv2 != null && mesh.uv2.Length > 0) { foreach (Vector2 u in mesh.uv2) { assimpMesh.TextureCoordinateChannels[1].Add(new Vector3D(u.x, 1f - u.y, 0)); } } assimpMesh.SetIndices(mesh.triangles, 3); /*if(bones != null) * { * foreach(Transform b in bones) * { * Bone bone = new Bone(); * bone.Name = b.name; * * UnityEngine.Matrix4x4 m = b.worldToLocalMatrix.inverse; * bone.OffsetMatrix = new Assimp.Matrix4x4( * m.m00, m.m01, m.m02, m.m03, * m.m10, m.m11, m.m12, m.m13, * m.m20, m.m21, m.m22, m.m23, * m.m30, m.m31, m.m32, m.m33 * ); * * assimpMesh.Bones.Add(bone); * } * * int vertId = 0; * * foreach(BoneWeight bw in mesh.boneWeights) * { * assimpMesh.Bones[bw.boneIndex0].VertexWeights.Add(new VertexWeight(vertId, bw.weight0)); * assimpMesh.Bones[bw.boneIndex1].VertexWeights.Add(new VertexWeight(vertId, bw.weight1)); * assimpMesh.Bones[bw.boneIndex2].VertexWeights.Add(new VertexWeight(vertId, bw.weight2)); * assimpMesh.Bones[bw.boneIndex3].VertexWeights.Add(new VertexWeight(vertId, bw.weight3)); * vertId++; * } * }*/ return(assimpMesh); }
public static void SaveToFile(string filename, DataStructures.MapObjects.Map map, string format) { Scene scene = new Scene(); Node rootNode = new Node(); rootNode.Name = "root"; scene.RootNode = rootNode; Node newNode = new Node(); Mesh mesh; int vertOffset; string[] textures = map.GetAllTextures().ToArray(); foreach (string texture in textures) { if (texture == "tooltextures/remove_face") { continue; } Material material = new Material(); material.Name = texture; TextureSlot textureSlot = new TextureSlot(texture + (File.Exists(texture + ".png") ? ".png" : (File.Exists(texture + ".jpeg") ? ".jpeg" : ".jpg")), TextureType.Diffuse, 0, TextureMapping.Plane, 0, 1.0f, TextureOperation.Multiply, Assimp.TextureWrapMode.Wrap, Assimp.TextureWrapMode.Wrap, 0); material.AddMaterialTexture(ref textureSlot); scene.Materials.Add(material); mesh = new Mesh(); if (format != "obj") // .obj files should have no mesh names so they are one proper mesh { mesh.Name = texture + "_mesh"; } mesh.MaterialIndex = scene.MaterialCount - 1; vertOffset = 0; List <int> indices = new List <int>(); IEnumerable <Face> faces = map.WorldSpawn.Find(x => x is Solid). OfType <Solid>(). SelectMany(x => x.Faces). Where(x => x.Texture.Name == texture); foreach (Face face in faces) { foreach (Vertex v in face.Vertices) { mesh.Vertices.Add(new Vector3D((float)v.Location.X, (float)v.Location.Z, (float)v.Location.Y)); mesh.Normals.Add(new Vector3D((float)face.Plane.Normal.X, (float)face.Plane.Normal.Z, (float)face.Plane.Normal.Y)); mesh.TextureCoordinateChannels[0].Add(new Vector3D((float)v.TextureU, (float)v.TextureV, 0)); } mesh.UVComponentCount[0] = 2; foreach (uint ind in face.GetTriangleIndices()) { indices.Add((int)ind + vertOffset); } vertOffset += face.Vertices.Count; } mesh.SetIndices(indices.ToArray(), 3); scene.Meshes.Add(mesh); newNode.MeshIndices.Add(scene.MeshCount - 1); } rootNode.Children.Add(newNode); new AssimpContext().ExportFile(scene, filename, format); }