//recursively calculates the bounding box of the whole model private void ComputeBoundingBox(Scene scene, Node node, ref Vector3 min, ref Vector3 max, ref Matrix transform) { Matrix previousTransform = transform; transform = Matrix.Multiply(previousTransform, FromMatrix(node.Transform)); if (node.HasMeshes) { foreach (int index in node.MeshIndices) { Assimp.Mesh mesh = scene.Meshes[index]; for (int i = 0; i < mesh.VertexCount; i++) { Vector3 tmp = FromVector(mesh.Vertices[i]); Vector4 result; Vector3.Transform(ref tmp, ref transform, out result); min.X = Math.Min(min.X, result.X); min.Y = Math.Min(min.Y, result.Y); min.Z = Math.Min(min.Z, result.Z); max.X = Math.Max(max.X, result.X); max.Y = Math.Max(max.Y, result.Y); max.Z = Math.Max(max.Z, result.Z); } } } //go down the hierarchy if children are present for (int i = 0; i < node.ChildCount; i++) { ComputeBoundingBox(scene, node.Children[i], ref min, ref max, ref transform); } transform = previousTransform; }
/// <summary> /// Sets the contents of the info pop-up given an assimp mesh. /// /// At the time this method is called, the mesh info popup's /// location has already been adjusted by the caller. /// </summary> public void Populate(Mesh mesh) { Debug.Assert(mesh != null); Debug.Assert(_owner != null); labelInfo.Text = string.Format("{0} Vertices\n{1} Faces\n", mesh.VertexCount, mesh.FaceCount); }
/// <summary> /// Import a mesh from a model file. /// </summary> /// <param name="path"></param> /// <returns></returns> public static Mesh Load(string path) { Mesh mesh = new Mesh() { Path = path }; a.AssimpContext context = new a.AssimpContext(); a.Scene scene = context.ImportFile(path, a.PostProcessSteps.Triangulate); a.Mesh aMesh = scene.Meshes[0]; mesh.vertices = new Vector4[aMesh.VertexCount]; mesh.normals = new Vector4[aMesh.VertexCount]; mesh.uvs = new Vector4[aMesh.VertexCount]; for (int i = 0; i < aMesh.VertexCount; i++) { a.Vector3D aVertex = aMesh.Vertices[i]; a.Vector3D aNormal = aMesh.Normals[i]; a.Vector3D aUv = aMesh.TextureCoordinateChannels[0][i]; mesh.vertices[i] = new Vector4(aVertex.X, aVertex.Y, aVertex.Z, 1f); mesh.normals[i] = new Vector4(aNormal.X, aNormal.Y, aNormal.Z, 0f); mesh.uvs[i] = new Vector4(aUv.X, aUv.Y, 0f, 0f); } mesh.indices = aMesh.GetIndices(); return(mesh); }
/// <summary> /// Constructs a RenderMesh for a given assimp mesh and uploads the /// required data to the GPU. /// </summary> /// <param name="mesh"></param> /// <exception cref="Exception">When any Gl errors occur during uploading</exception> public RenderMesh(Mesh mesh) { Debug.Assert(mesh != null); _mesh = mesh; Upload(out _vbo); }
void WriteIndices(Mesh assimpMesh, ModelData.MeshPart meshPart, ModelData.IndexBuffer indexBuffer) { // Write all indices var indices = assimpMesh.GetIntIndices(); indexBuffer.Count = indices.Length; meshPart.IndexBufferRange.Count = indices.Length; if (meshPart.VertexBufferRange.Count < 65536) { // Write only short indices if count is less than the size of a short indexBuffer.Buffer = new byte[indices.Length * 2]; using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true)) foreach (int index in indices) { indexStream.Write((ushort)index); } } else { // Otherwise, use full 32-bit precision to store indices indexBuffer.Buffer = new byte[indices.Length * 4]; using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true)) indexStream.WriteRange(indices); } // Update the MaximumBufferSizeInBytes needed to load this model if (indexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes) { model.MaximumBufferSizeInBytes = indexBuffer.Buffer.Length; } }
private static void ProcessMesh(ref Assimp.Mesh mesh, ref Mesh result) { if (mesh != null) { if (!string.IsNullOrWhiteSpace(mesh.Name)) { result.Name = mesh.Name; } List <float> vertices = new List <float>(); foreach (Vector3D pos in mesh.Vertices) { vertices.Add(pos.X); vertices.Add(pos.Y); vertices.Add(pos.Z); } result.Vertices = vertices.ToArray(); List <float> uvs = new List <float>(); foreach (Vector3D uv in mesh.TextureCoordinateChannels[0]) { uvs.Add(uv.X); uvs.Add(1.0f - uv.Y); } result.UVs = uvs.ToArray(); List <float> normals = new List <float>(); foreach (Vector3D normal in mesh.Normals) { normals.Add(normal.X); normals.Add(normal.Y); normals.Add(normal.Z); } result.Normals = normals.ToArray(); result.Indices = mesh.GetIndices().Select(i => (uint)i).ToArray(); } }
public void SetIndices( Assimp.Mesh sourceMesh, VRageRender.Import.Mesh mesh, int[] indices, List <Vector3> vertices, int matHash) { MyMeshPartInfo myMeshPartInfo; if (!this.m_partContainer.TryGetValue(matHash, out myMeshPartInfo)) { myMeshPartInfo = new MyMeshPartInfo(); myMeshPartInfo.m_MaterialHash = matHash; this.m_partContainer.Add(matHash, myMeshPartInfo); } mesh.StartIndex = myMeshPartInfo.m_indices.Count; mesh.IndexCount = indices.Length; int vertexOffset = mesh.VertexOffset; for (int index = 0; index < sourceMesh.FaceCount * 3; index += 3) { int num1 = indices[index] + vertexOffset; int num2 = indices[index + 1] + vertexOffset; int num3 = indices[index + 2] + vertexOffset; myMeshPartInfo.m_indices.Add(num1); myMeshPartInfo.m_indices.Add(num2); myMeshPartInfo.m_indices.Add(num3); } }
private void ProcessMesh(Assimp.Mesh mesh, Scene scene) { List <MeshVertex> vertices = new List <MeshVertex>(); List <uint> indices = new List <uint>(); for (int i = 0; i < mesh.VertexCount; i++) { Vector3 position = new Vector3(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z); Vector3 normal = new Vector3(mesh.Normals[i].X, mesh.Normals[i].Y, mesh.Normals[i].Z); Vector2 texCoords = Vector2.Zero; if (mesh.TextureCoordinateChannelCount > 0) { texCoords = new Vector2(mesh.TextureCoordinateChannels[0][i].X, mesh.TextureCoordinateChannels[0][i].Y); } vertices.Add(new MeshVertex(position, normal, texCoords)); } for (int i = 0; i < mesh.FaceCount; i++) { var face = mesh.Faces[i]; for (int j = 0; j < face.IndexCount; j++) { indices.Add((uint)face.Indices[j]); } } new Mesh(m_ModelPath, m_SpawnedMeshes, vertices.ToArray(), indices.ToArray()); m_SpawnedMeshes++; }
// TODO(acgessler): Bones. public EditVertex(Mesh mesh, int index) { TexCoord = new Vector3D?[MaxTexcoordChannels]; Color = new Color4D?[MaxColorChannels]; Position = mesh.Vertices[index]; AdjacentVertices = new HashSet<EditVertex>(); if (mesh.HasNormals) { Normal = mesh.Normals[index]; } if (mesh.HasTangentBasis) { Tangent = mesh.Tangents[index]; Bitangent = mesh.BiTangents[index]; } for (int i = 0; i < Math.Min(MaxTexcoordChannels, mesh.TextureCoordinateChannelCount); ++i) { TexCoord[i] = mesh.TextureCoordinateChannels[i][index]; } for (int i = 0; i < Math.Min(MaxColorChannels, mesh.VertexColorChannelCount); ++i) { Color[i] = mesh.VertexColorChannels[i][index]; } }
Mesh ConvertMesh(AssimpMesh M, Material[] Materials) { Mesh Msh = new Mesh(); Vector3[] Verts = M.Vertices.Select((V) => new Vector3(V.X, V.Y, V.Z)).ToArray(); Msh.SetVertices(Verts); Vector2[] UVs = M.TextureCoordinateChannels[0].Select((V) => new Vector2(V.X, V.Y)).ToArray(); if (UVs.Length > 0) { Msh.SetUVs(UVs); } Vector4[] Colors = M.VertexColorChannels[0].Select((C) => new Vector4(C.R, C.G, C.B, C.A)).ToArray(); if (Colors.Length > 0) { Msh.SetColors(Colors); } uint[] Indices = M.GetUnsignedIndices(); if (Indices.Length > 0) { Msh.SetElements(Indices); } if (Materials != null) { Msh.Material = Materials[M.MaterialIndex]; } return(Msh); }
/// <summary> /// Determines the best target scene node for the mesh. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="aiMesh"></param> /// <param name="aiNode"></param> /// <param name="nodeSearchFunc"></param> /// <param name="fallback"></param> /// <returns></returns> public static T DetermineBestTargetNode <T>(Assimp.Mesh aiMesh, Assimp.Node aiNode, Func <string, T> nodeSearchFunc, T fallback) { if (aiMesh.BoneCount > 1) { // Select node to which the mesh is weighted most var boneWeightCoverage = CalculateBoneWeightCoverage(aiMesh); var maxCoverage = boneWeightCoverage.Max(x => x.Coverage); var bestTargetBone = boneWeightCoverage.First(x => x.Coverage == maxCoverage).Bone; return(nodeSearchFunc(bestTargetBone.Name)); } else if (aiMesh.BoneCount == 1) { // Use our only bone as the target node return(nodeSearchFunc(aiMesh.Bones[0].Name)); } else { // Try to find a parent of the mesh's ainode that exists within the existing hierarchy var aiNodeParent = aiNode.Parent; while (aiNodeParent != null) { var nodeParent = nodeSearchFunc(aiNodeParent.Name); if (nodeParent != null) { return(nodeParent); } aiNodeParent = aiNodeParent.Parent; } // Return fallback return(fallback); } }
private void _initMesh(Assimp.Mesh mesh) { Assimp.Vector3D Zero3D = new Assimp.Vector3D(0f); if (mesh.PrimitiveType == Assimp.PrimitiveType.Triangle) { // Populate the vertex attribute vectors for (int i = 0; i < mesh.VertexCount; i++) { Assimp.Vector3D pos = mesh.Vertices[i]; Assimp.Vector3D normal = mesh.Normals[i]; Assimp.Vector3D uv = mesh.HasTextureCoords(0) ? mesh.TextureCoordinateChannels[0][i] : Zero3D; positions.Add(new Vector3f(pos.X, pos.Y, pos.Z)); normals.Add(new Vector3f(normal.X, normal.Y, normal.Z)); uvs.Add(new Vector2f(uv.X, uv.Y)); } // Populate the index buffer for (int i = 0; i < mesh.FaceCount; i++) { Assimp.Face face = mesh.Faces[i]; // TODO: Find a suitable way to draw vertices... // Now only support triangulated faces indices.Add(face.Indices[0]); indices.Add(face.Indices[1]); indices.Add(face.Indices[2]); } } }
public DX11IndexedGeometry LoadFromMesh(Assimp.Mesh mesh, AssimpLoadInformation loadInfo, bool allowRawView = false) { uint[] inds = mesh.GetIndices(); if (inds.Length > 0 && mesh.VertexCount > 0) { int vertexsize; var layout = mesh.InputLayout(loadInfo, out vertexsize); BoundingBox bb; DataStream ds = mesh.LoadVertices(loadInfo, vertexsize, out bb); DX11IndexedGeometry geom = new DX11IndexedGeometry(device) { HasBoundingBox = true, BoundingBox = bb, IndexBuffer = DX11IndexBuffer.CreateImmutable(device, inds, allowRawView), InputLayout = layout, PrimitiveType = "AssimpModel", Tag = null, Topology = SharpDX.Direct3D.PrimitiveTopology.TriangleList, VertexBuffer = DX11VertexBuffer.CreateImmutable(device, mesh.VertexCount, vertexsize, ds, allowRawView) }; ds.Dispose(); return(geom); } return(null); }
/// <summary> /// Gets vertex data from a given <see cref="AssimpMesh"/>. /// </summary> /// <param name="sceneMesh">The <see cref="AssimpMesh"/> to get vertex information from.</param> /// <param name="boneIndexByName">A lookup of bone index by name information.</param> /// <returns>An output list of vertices.</returns> private Vertex[] GetMeshVertices(AssimpMesh sceneMesh, Dictionary <string, uint> boneIndexByName) { var positions = sceneMesh.Vertices; var normals = sceneMesh.Normals; var tangents = sceneMesh.Tangents; var colors = sceneMesh.HasVertexColors(0) ? sceneMesh.VertexColorChannels[0] : null; var textureCoordinates = sceneMesh.HasTextureCoords(0) ? sceneMesh.TextureCoordinateChannels[0] : null; var boneWeightsByVertexIndex = GetBoneWeightsByVertexIndex(boneIndexByName, sceneMesh); var vertices = new List <Vertex>(); for (var i = 0; i < positions.Count; i++) { var position = positions[i]; var normal = normals[i]; var tangent = tangents[i]; var color = colors?[i]; var textureCoordinate = textureCoordinates?[i]; TryGetBoneIndicesAndWeights(boneWeightsByVertexIndex, i, out var boneIndices, out var boneWeights); vertices.Add(new Vertex(new Vector3(position.X, position.Y, position.Z), new Vector3(normal.X, normal.Y, normal.Z), new Vector3(tangent.X, tangent.Y, tangent.Z), color != null ? new Color(color.Value.R, color.Value.G, color.Value.B, color.Value.A) : new Color(1.0f, 1.0f, 1.0f, 1.0f), textureCoordinate != null ? new Vector2(textureCoordinate.Value.X, textureCoordinate.Value.Y) : Vector2.Zero, new ReadOnlyCollection <uint>(boneIndices), new ReadOnlyCollection <float>(boneWeights))); } return(vertices.ToArray()); }
internal void LoadPrimitveFromFile(string fileName, out DebugVertexType[] vertices, out UInt16[] indices) { Assimp.Scene scene = m_importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessPreset.ConvertToLeftHanded); // Loaded primitive files should always only contain a single mesh so we load only the first mesh if (scene.HasMeshes) { Assimp.Mesh assimpMesh = scene.Meshes[0]; vertices = new DebugVertexType[assimpMesh.Vertices.Count]; indices = new UInt16[assimpMesh.GetIndices().Length]; for (int i = 0; i < assimpMesh.Vertices.Count; ++i) { Vector3 position = FromAssimpVector(assimpMesh.Vertices[i]); vertices[i].position = position; } for (int i = 0; i < assimpMesh.GetIndices().Length; i++) { int index = assimpMesh.GetIndices()[i]; indices[i] = (UInt16)index; } } else { vertices = new DebugVertexType[0]; indices = new UInt16[0]; } }
internal BoneByVertexMap(Mesh mesh) { Debug.Assert(mesh != null); _mesh = mesh; _offsets = new uint[mesh.VertexCount]; _countBones = new uint[mesh.VertexCount]; if (_mesh.BoneCount == 0) { _bonesByVertex = new IndexWeightTuple[0]; return; } // get per-vertex bone influence counts var countWeights = 0; for (var i = 0; i < mesh.BoneCount; ++i) { var bone = mesh.Bones[i]; countWeights += bone.VertexWeightCount; for (int j = 0; j < bone.VertexWeightCount; ++j) { var weight = bone.VertexWeights[j]; ++_countBones[weight.VertexID]; } } _bonesByVertex = new IndexWeightTuple[countWeights]; // generate offset table uint sum = 0; for (var i = 0; i < _mesh.VertexCount; ++i) { _offsets[i] = sum; sum += _countBones[i]; } // populate vertex-to-bone table, using the offset table // to keep track of how many bones have already been // written for a vertex. for (var i = 0; i < mesh.BoneCount; ++i) { var bone = mesh.Bones[i]; countWeights += bone.VertexWeightCount; for (int j = 0; j < bone.VertexWeightCount; ++j) { var weight = bone.VertexWeights[j]; BonesByVertex[_offsets[weight.VertexID]++] = new IndexWeightTuple(i, weight.Weight); } } // undo previous changes to the offset table for (var i = 0; i < _mesh.VertexCount; ++i) { _offsets[i] -= _countBones[i]; } Debug.Assert(_offsets[0] == 0); }
private Mesh ProcessMesh(Assimp.Mesh aMesh, Scene scene) { Mesh mesh = new Mesh(); for (int i = 0; i < aMesh.VertexCount; i++) { Vertex vertex = new Vertex { Position = new Vector3(aMesh.Vertices[i].X, aMesh.Vertices[i].Y, aMesh.Vertices[i].Z) }; if (aMesh.HasNormals) { vertex.Normals = new Vector3(aMesh.Normals[i].X, aMesh.Normals[i].Y, aMesh.Normals[i].Z); } if (aMesh.HasTextureCoords(0)) { vertex.TexCoords = new Vector2(aMesh.TextureCoordinateChannels[0][i].X, aMesh.TextureCoordinateChannels[0][i].Y); if (aMesh.HasTangentBasis) { vertex.Tangent = new Vector3(aMesh.Tangents[i].X, aMesh.Tangents[i].Y, aMesh.Tangents[i].Z); vertex.Bitangent = new Vector3(aMesh.BiTangents[i].X, aMesh.BiTangents[i].Y, aMesh.BiTangents[i].Z); } } else { vertex.TexCoords = Vector2.Zero; } mesh.Vertices = mesh.Vertices.Append(vertex).ToArray(); } for (int i = 0; i < aMesh.FaceCount; i++) { for (int j = 0; j < aMesh.Faces[i].IndexCount; j++) { mesh.Indices = mesh.Indices.Append(aMesh.Faces[i].Indices[j]).ToArray(); } } var material = scene.Materials[aMesh.MaterialIndex]; List <Texture> diffuseMaps = LoadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse"); mesh.Textures.AddRange(diffuseMaps); List <Texture> specularMaps = LoadMaterialTextures(material, TextureType.Specular, "texture_specular"); mesh.Textures.AddRange(specularMaps); List <Texture> normalMaps = LoadMaterialTextures(material, TextureType.Normals, "texture_normal"); mesh.Textures.AddRange(normalMaps); List <Texture> heightMaps = LoadMaterialTextures(material, TextureType.Height, "texture_height"); mesh.Textures.AddRange(heightMaps); mesh.SetupMesh(); return(mesh); }
Mesh processMesh(Assimp.Mesh mesh, Assimp.Scene scene) { List <Vertex> vertices = null; List <int> indices = null; List <Texture> textures = null; for (int i = 0; i < mesh.VertexCount; i++) { Vertex vert = new Vertex(); Vector3 vec = new Vector3(); vec.X = mesh.Vertices[i].X; vec.Y = mesh.Vertices[i].Y; vec.Z = mesh.Vertices[i].Z; vert.position = vec; vec.X = mesh.Normals[i].X; vec.Y = mesh.Normals[i].Y; vec.Z = mesh.Normals[i].Z; vert.normal = vec; if (mesh.HasTextureCoords(0)) { Vector2 vec2 = new Vector2(); vec2.X = mesh.TextureCoordinateChannels[0][i].X; vec2.Y = mesh.TextureCoordinateChannels[0][i].Y; vert.texCoord = vec2; } else { vert.texCoord = new Vector2(0, 0); } vertices.Add(vert); } for (int i = 0; i < mesh.FaceCount; i++) { Assimp.Face face = new Face(); face = mesh.Faces[i]; for (int j = 0; j < face.IndexCount; j++) { indices.Add(face.Indices[j]); } } if (mesh.MaterialIndex >= 0) { Material material = scene.Materials[mesh.MaterialIndex]; List <Texture> diffuseMaps = new List <Texture>(); diffuseMaps.AddRange(loadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse")); textures.InsertRange(textures.Count + 1, diffuseMaps); List <Texture> specularMaps = new List <Texture>(); specularMaps.AddRange(loadMaterialTextures(material, TextureType.Specular, "texture_specular")); textures.InsertRange(textures.Count + 1, specularMaps); } return(new Mesh(vertices, indices, textures)); }
private void processNode(Node node, Assimp.Scene scene) { for (int i = 0; i < node.MeshCount; i++) { Assimp.Mesh mesh = scene.Meshes[node.MeshIndices[i]]; meshes.Add(processMesh(mesh, scene)); } }
public ResourceManager(GraphicsDevice device) { _texturesByFilePath = new Dictionary<string, Texture2D>(); _meshCache = new Dictionary<string, ModelMesh>(); _device = device; _cubeMesh = new Mesh(_device, Primitives.GenerateCubeData()); _billboardMesh = new Mesh(_device, Primitives.GenerateQuadForYBillboard()); }
public void SetMesh(MainWindow host, Mesh mesh, string meshName) { Debug.Assert(mesh != null); Debug.Assert(host != null); Debug.Assert(meshName != null); _mesh = mesh; _host = host; labelVertexCount.Text = mesh.VertexCount + " Vertices"; labelFaceCount.Text = mesh.FaceCount + " Faces"; Text = meshName + " - Details"; checkedListBoxPerFace.CheckOnClick = false; checkedListBoxPerFace.SetItemCheckState(0, mesh.PrimitiveType.HasFlag(PrimitiveType.Triangle) ? CheckState.Checked : CheckState.Unchecked); checkedListBoxPerFace.SetItemCheckState(1, mesh.PrimitiveType.HasFlag(PrimitiveType.Line) ? CheckState.Checked : CheckState.Unchecked); checkedListBoxPerFace.SetItemCheckState(2, mesh.PrimitiveType.HasFlag(PrimitiveType.Point) ? CheckState.Checked : CheckState.Unchecked); checkedListBoxPerVertex.CheckOnClick = false; checkedListBoxPerVertex.SetItemCheckState(0, CheckState.Checked); checkedListBoxPerVertex.SetItemCheckState(1, mesh.HasNormals ? CheckState.Checked : CheckState.Unchecked); checkedListBoxPerVertex.SetItemCheckState(2, mesh.HasTangentBasis ? CheckState.Checked : CheckState.Unchecked); Debug.Assert(mesh.TextureCoordinateChannels.Length >= 4); for (var i = 0; i < 4; ++i) { checkedListBoxPerVertex.SetItemCheckState(3 + i, mesh.HasTextureCoords(i) ? CheckState.Checked : CheckState.Unchecked); } Debug.Assert(mesh.VertexColorChannels.Length >= 4); for (var i = 0; i < 4; ++i) { checkedListBoxPerVertex.SetItemCheckState(7 + i, mesh.HasVertexColors(i) ? CheckState.Checked : CheckState.Unchecked); } checkedListBoxPerVertex.SetItemCheckState(11, mesh.HasBones ? CheckState.Checked : CheckState.Unchecked); }
void WriteBarycentricVertices(Mesh assimpMesh, ModelData.MeshPart meshPart, ModelData.VertexBuffer vertexBuffer, int vertexBufferElementSize) { //System.Diagnostics.Debugger.Launch(); int[] indices = assimpMesh.GetIntIndices(); int indexCount = indices.Length; // Write all vertices meshPart.VertexBufferRange.Count = indexCount; vertexBuffer.Count = indexCount; vertexBuffer.Buffer = new byte[vertexBufferElementSize * indexCount]; // Update the MaximumBufferSizeInBytes needed to load this model if (vertexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes) { model.MaximumBufferSizeInBytes = vertexBuffer.Buffer.Length; } var vertexStream = DataStream.Create(vertexBuffer.Buffer, true, true); boundingPoints = new Vector3[indexCount]; var newVertices = new VertexPositionNormalTexture[indices.Length]; for (int i = 0; i < indexCount; i++) { try { int i0 = indices[i]; var v0 = assimpMesh.Vertices[i0]; var v = new Vector3(v0.X, v0.Y, v0.Z); var n0 = assimpMesh.Normals[i0]; var n = new Vector3(n0.X, n0.Y, n0.Z); var uv = assimpMesh.GetTextureCoords(0)[i0]; var t = new Vector2(uv.X, uv.Y); // Store bounding points for BoundingSphere pre-calculation boundingPoints[currentBoundingPointIndex++] = v; newVertices[i0] = new VertexPositionNormalTexture(v, n, t); } catch (Exception ex) { Debug.WriteLine("!" + ex); } } var barycentricVertices = ModelEditor.ConvertToBarycentricEdgeNormalVertices(newVertices, indices); foreach (var vertex in barycentricVertices) { vertexStream.Write(vertex.Position); vertexStream.Write(vertex.Normal); vertexStream.Write(vertex.TextureUV); vertexStream.Write(vertex.Barycentric); } vertexStream.Dispose(); }
/// <summary> /// Processes a Mesh in an Assimp Scene /// </summary> /// <param name="mesh">The Current mesh to process</param> /// <param name="s">The root scene</param> /// <param name="dir">The Relative directory of the Mesh File</param> /// <returns>The mesh loaded.</returns> private static Mesh processMesh(AssimpMesh mesh, Scene s, string dir, object handleIdentifier) { List <Vertex> vertices = new List <Vertex>(); List <uint> indices = new List <uint>(); List <Texture> textures = new List <Texture>(); Logger.Log(DebugChannel.Log | DebugChannel.EngineIO, "Converting Imported Mesh File Structure to GameEngine Engine Structure", 3); Logger.Log(DebugChannel.Log | DebugChannel.EngineIO, "Copying Vertex Data...", 2); for (int i = 0; i < mesh.VertexCount; i++) { Vector3D vert = mesh.Vertices[i]; Vector3D norm = mesh.Normals[i]; Vector3D tan = mesh.HasTangentBasis ? mesh.Tangents[i] : new Vector3D(0); Vector3D bit = mesh.HasTangentBasis ? mesh.BiTangents[i] : new Vector3D(0); Vector3D uv = mesh.HasTextureCoords(0) ? mesh.TextureCoordinateChannels[0][i] : new Vector3D(0); Vertex v = new Vertex { Position = new Vector3(vert.X, vert.Y, vert.Z), Normal = new Vector3(norm.X, norm.Y, norm.Z), UV = new Vector2(uv.X, uv.Y), Bittangent = new Vector3(bit.X, bit.Y, bit.Z), Tangent = new Vector3(tan.X, tan.Y, tan.Z) }; vertices.Add(v); } Logger.Log(DebugChannel.Log | DebugChannel.EngineIO, "Calculating Indices...", 2); for (int i = 0; i < mesh.FaceCount; i++) { Face f = mesh.Faces[i]; indices.AddRange(f.Indices.Select(x => (uint)x)); } Material m = s.Materials[mesh.MaterialIndex]; Logger.Log(DebugChannel.Log | DebugChannel.EngineIO, "Loading Baked Material: " + m.Name, 2); textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Diffuse, dir)); textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Specular, dir)); textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Normals, dir)); textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Height, dir)); setupMesh(indices.ToArray(), vertices.ToArray(), out int vao, out int vbo, out int ebo); long bytes = indices.Count * sizeof(uint) + vertices.Count * Vertex.VERTEX_BYTE_SIZE; return(new Mesh(ebo, vbo, vao, indices.Count, bytes, false, handleIdentifier)); }
private static Mesh GetMesh(Assimp.Scene scene, Node node = null, Assimp.Mesh mesh = null, bool Root = true) { Mesh result = InitMesh(ref scene, ref node, ref Root); ProcessMesh(ref mesh, ref result); ProcessNode(ref scene, ref node, ref mesh, ref result); result.UpdateBuffers(); return(result); }
private static Mesh ProcessMesh(Assimp.Mesh mesh) { var positions = ProcessVertices(mesh); var textures = ProcessTextCoord(mesh); var normals = ProcessNormals(mesh); var indices = ProcessIndices(mesh); return(new Mesh(positions, normals, textures, indices)); }
public static void DrawNormals(Node node, int meshIndex, Mesh mesh, CpuSkinningEvaluator skinner, float invGlobalScale, Matrix4 transform) { if (!mesh.HasNormals) { return; } // The normal directions are transformed using the transpose(inverse(transform)). // This ensures correct direction is used when non-uniform scaling is present. Matrix4 normalMatrix = transform; normalMatrix.Invert(); normalMatrix.Transpose(); // Scale by scene size because the scene will be resized to fit // the unit box, but the normals should have a fixed length. var scale = invGlobalScale * 0.05f; GL.Begin(BeginMode.Lines); GL.Disable(EnableCap.Lighting); GL.Disable(EnableCap.Texture2D); GL.Enable(EnableCap.ColorMaterial); GL.Color4(new Color4(0.0f, 1.0f, 0.0f, 1.0f)); for (uint i = 0; i < mesh.VertexCount; ++i) { Vector3 v; if (skinner != null && mesh.HasBones) { skinner.GetTransformedVertexPosition(node, mesh, i, out v); } else { v = AssimpToOpenTk.FromVector(mesh.Vertices[(int)i]); } v = Vector4.Transform(new Vector4(v, 1.0f), transform).Xyz; // Skip dividing by W component. It should always be 1, here. Vector3 n; if (skinner != null) { skinner.GetTransformedVertexNormal(node, mesh, i, out n); } else { n = AssimpToOpenTk.FromVector(mesh.Normals[(int)i]); } n = Vector4.Transform(new Vector4(n, 0.0f), normalMatrix).Xyz; // Toss the W component. It is non-sensical for normals. n.Normalize(); GL.Vertex3(v); GL.Vertex3(v + n * scale); } GL.End(); GL.Disable(EnableCap.ColorMaterial); }
public void Construct(Stream stream, Action <Vector3, Vector3, Vector2> appendVertex, Action <Int3> appendIndex, int index, string formatHint) { Assimp.AssimpImporter importer = new AssimpImporter(); Scene scene = importer.ImportFileFromStream(stream, PostProcessPreset.ConvertToLeftHanded | PostProcessPreset.TargetRealTimeQuality, formatHint); Assimp.Mesh mesh = scene.Meshes[index % scene.MeshCount]; int offset = 0; Construct(mesh, appendVertex, appendIndex, ref offset); }
private Mesh ProcessMesh(Assimp.Mesh mesh, Scene scene) { List <Vertex> vertices = new List <Vertex>(); List <uint> indices = new List <uint>(); List <Texture> textures = new List <Texture>(); //loading vertex for (int i = 0; i < mesh.VertexCount; i++) { Vertex v; v.position.X = mesh.Vertices[i].X; v.position.Y = mesh.Vertices[i].Y; v.position.Z = mesh.Vertices[i].Z; v.normal.X = mesh.Normals[i].X; v.normal.Y = mesh.Normals[i].Y; v.normal.Z = mesh.Normals[i].Z; v.texCoord.X = mesh.TextureCoordinateChannels[0][i].X; v.texCoord.Y = mesh.TextureCoordinateChannels[0][i].Y; vertices.Add(v); } //loading indices for (int i = 0; i < mesh.FaceCount; i++) { var face = mesh.Faces[i]; for (int j = 0; j < face.IndexCount; j++) { indices.Add((uint)face.Indices[j]); } } //loading material if (mesh.MaterialIndex >= 0) { var mat = scene.Materials[mesh.MaterialIndex]; List <Texture> texDiffuse = LoadMaterialTextures(mat, TextureType.Diffuse, "texture_diffuse"); textures.AddRange(texDiffuse); List <Texture> texSpecular = LoadMaterialTextures(mat, TextureType.Specular, "texture_specular"); if (texSpecular.Count == 0) { texSpecular = LoadMaterialTextures(mat, TextureType.Height, "texture_specular"); } textures.AddRange(texSpecular); } return(new Mesh(vertices, indices, textures)); }
void getVertexBoneData(Assimp.Mesh mesh) { int weightsPerVertex = 4; //we should set this once if (myModel.boneCount == 0) { myModel.boneCount = mesh.BoneCount; foreach (Bone b in mesh.Bones) { if (boneNames.Contains(b.Name) == false) { boneNames.Add(b.Name); bones.Add(toMatrix(b.OffsetMatrix)); } } } else { if (myModel.boneCount != mesh.BoneCount) { Warn.print("Weird model. Meshes have different bones"); throw new Exception("Weird Model"); } } for (int i = 0; i < mesh.BoneCount; i++) { Bone b = mesh.Bones[i]; if (b.HasVertexWeights == false) { continue; } foreach (VertexWeight weight in b.VertexWeights) { V3N3T2B4W4 vert = myVerts[weight.VertexID + currVertOffset]; //find the next available weight (if there is space) for (int k = 0; k < weightsPerVertex; k++) { if (vert.BoneWeight[k] == 0.0f) { vert.BoneId[k] = (float)i; vert.BoneWeight[k] = weight.Weight; break; } } myVerts[weight.VertexID + currVertOffset] = vert; } } }
private Core.Entities.Mesh convertAssimpToEngineFormat(Mesh assimpMesh) { Core.Entities.Mesh mesh = new Core.Entities.Mesh(); mesh.Vertices = assimpMesh.Vertices.AssimpListToOpentkVector().ToArray(); mesh.Normals = assimpMesh.Normals.AssimpListToOpentkVector().ToArray(); mesh.UvCoords = assimpMesh.TextureCoordinateChannels[0].GetUVCoordChanel().ToArray(); mesh.Indeces = assimpMesh.GetIndices(); return(mesh); }
void getVertexBoneData(Assimp.Mesh mesh) { /* * int weightsPerVertex = 4; * * //we should set this once * if (myModel.boneCount == 0) * { * myModel.boneCount = mesh.BoneCount; * foreach (Bone b in mesh.Bones) * { * if (boneNames.Contains(b.Name) == false) * { * boneNames.Add(b.Name); * bones.Add(toMatrix(b.OffsetMatrix)); * } * } * } * else * { * if(myModel.boneCount != mesh.BoneCount) * { * Warn.print("Weird model. Meshes have different bones"); * throw new Exception("Weird Model"); * } * } * * for(int i = 0; i < mesh.BoneCount; i++) * { * Bone b = mesh.Bones[i]; * * if (b.HasVertexWeights == false) * continue; * * foreach(VertexWeight weight in b.VertexWeights) * { * V3N3T2B4W4 vert = myVerts[weight.VertexID + currVertOffset]; * * //find the next available weight (if there is space) * for(int k = 0; k < weightsPerVertex; k++) * { * if(vert.BoneWeight[k] == 0.0f) * { * vert.BoneId[k] = (float)i; * vert.BoneWeight[k] = weight.Weight; * break; * } * } * * myVerts[weight.VertexID + currVertOffset] = vert; * } * } */ }
dynamic[] GetWAndB(Assimp.Mesh m, int i) { var b = m.Bones.Where(bb => bb.HasVertexWeights && bb.VertexWeights.Any(tt => tt.VertexID == i)) .Select(x => new { Id = _bones.FindIndex(y => y.Name.Equals(x.Name)), Wt = x.VertexWeights.First(y => y.VertexID == i).Weight }).ToList(); return(b.ToArray()); }
static meshData ProcessMesh(Assimp.Mesh mesh, Assimp.Scene scene) { Vector3[] post = mesh.Vertices.Select(x => x.V()).ToArray(); Vector3[] norm = mesh.Normals.Select(x => x.V()).ToArray(); Vector3[] tang = mesh.Tangents.Select(x => x.V()).ToArray(); Vector2[] uves = mesh.TextureCoordinateChannels[0].Select(x => x.VX()).ToArray(); int[] inde = mesh.GetIndices(); var materialIndex = mesh.MaterialIndex; return(new meshData(post, inde, norm, tang, uves)); }
public CachedMeshData(Scene scene, Mesh source) { Debug.Assert(source.HasBones, "source mesh needs to have bones"); _scene = scene; _source = source; _cachedPositions = new Vector3[source.VertexCount]; _cachedNormals = new Vector3[source.VertexCount]; _boneMap = new BoneByVertexMap(source); }
void processNode(Node node, Scene scene) { for (int i = 0; i < node.MeshCount; i++) { Assimp.Mesh mesh = scene.Meshes[node.MeshIndices[i]]; meshes.Add(processMesh(mesh, scene)); } for (int i = 0; i < node.ChildCount; i++) { processNode(node.Children[i], scene); } }
private void proccessNode(ai.Node node, ai.Scene scene, MeshLoader loader) { foreach (int index in node.MeshIndices) { ai.Mesh mesh = scene.Meshes[index]; Meshes.Add(loader(mesh, scene)); } foreach (ai.Node child in node.Children) { proccessNode(child, scene, loader); } }
private void processNode(Node node, Scene scene) { for (int i = 0; i < node.MeshCount; i++) { Mesh mesh = scene.Meshes[i]; meshes.Add(mesh); } for (int i = 0; i < node.ChildCount; i++) { processNode(node.Children[i], scene); } }
private void ProcessNode(Assimp.Node node, Assimp.Scene scene) { for (int i = 0; i < node.MeshCount; i++) { Assimp.Mesh amesh = scene.Meshes[node.MeshIndices[i]]; _meshes.Add(ProcessMesh(amesh, scene)); } for (int i = 0; i < node.ChildCount; i++) { ProcessNode(node.Children[i], scene); } }
public override void ApplyMaterial(Mesh mesh, Material mat, bool textured, bool shaded) { ShaderGen.GenFlags flags = 0; if (textured) { flags |= ShaderGen.GenFlags.ColorMap; } if (shaded) { flags |= ShaderGen.GenFlags.Lighting; } Shader shader = _shaderGen.GenerateOrGetFromCache(flags); shader.BindIfNecessary(); }
public static void DrawNormals(Node node, int meshIndex, Mesh mesh, CpuSkinningEvaluator skinner, float invGlobalScale) { if (!mesh.HasNormals) { return; } // Scale by scene size because the scene will be resized to fit // the unit box but the normals should have a fixed length var scale = invGlobalScale * 0.05f; GL.Begin(BeginMode.Lines); GL.Disable(EnableCap.Lighting); GL.Disable(EnableCap.Texture2D); GL.Enable(EnableCap.ColorMaterial); GL.Color4(new Color4(0.0f, 1.0f, 0.0f, 1.0f)); for (uint i = 0; i < mesh.VertexCount; ++i) { Vector3 v; if (skinner != null && mesh.HasBones) { skinner.GetTransformedVertexPosition(node, meshIndex, i, out v); } else { v = AssimpToOpenTk.FromVector(mesh.Vertices[(int)i]); } Vector3 n; if (skinner != null) { skinner.GetTransformedVertexNormal(node, meshIndex, i, out n); } else { n = AssimpToOpenTk.FromVector(mesh.Normals[(int)i]); } GL.Vertex3(v); GL.Vertex3(v + n * scale); } GL.End(); GL.Disable(EnableCap.ColorMaterial); }
public static void ClearMesh(Mesh mesh) { mesh.Vertices.Clear(); mesh.Normals.Clear(); mesh.Tangents.Clear(); mesh.BiTangents.Clear(); for (int i = 0; i < AiDefines.AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { mesh.TextureCoordinateChannels[i].Clear(); } for (int i = 0; i < AiDefines.AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { mesh.VertexColorChannels[i].Clear(); } mesh.Faces.Clear(); mesh.PrimitiveType = 0; }
/// <summary> /// This is an expensive operation due to EditMesh construction, avoid. /// </summary> /// <param name="mesh"></param> public NormalVectorGenerator(Mesh mesh) { Debug.Assert(!mesh.PrimitiveType.HasFlag(PrimitiveType.Polygon)); _mesh = mesh; lock (_mesh) { _editMesh = new EditMesh(_mesh); } lock (ThreadPoolMutex) { if (_threadPool != null) return; int cpuCount = Environment.ProcessorCount; // One thread is busy rendering, so many extra threads that do not block on IO // (which our computation-heavy jobs don't) easily starve the GUI. Thus, // always reserve 25% and at least one core. int jobCount = Math.Max(1, (cpuCount * 3) / 4); _threadPool = new SmartThreadPool(1000, jobCount, jobCount); } }
public static void DeepCopy(Mesh dest, Mesh src) { ShallowCopy(dest, src); dest.Vertices = new List<Vector3D>(src.Vertices); dest.Normals = new List<Vector3D>(src.Normals); dest.Tangents = new List<Vector3D>(src.Tangents); dest.BiTangents = new List<Vector3D>(src.BiTangents); dest.TextureCoordinateChannels = new List<Vector3D>[AiDefines.AI_MAX_NUMBER_OF_TEXTURECOORDS]; for (int i = 0; i < AiDefines.AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { dest.TextureCoordinateChannels[i] = new List<Vector3D>(src.TextureCoordinateChannels[i]); } dest.VertexColorChannels = new List<Color4D>[AiDefines.AI_MAX_NUMBER_OF_COLOR_SETS]; for (int i = 0; i < AiDefines.AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { dest.VertexColorChannels[i] = new List<Color4D>(src.VertexColorChannels[i]); } dest.Faces = new List<Face>(src.Faces); for (int i = 0; i < dest.Faces.Count; ++i) { dest.Faces[i] = new Face(dest.Faces[i].Indices.ToArray()); } // TODO(acgessler): Handle bones. }
public static Mesh ShallowCopy(Mesh src) { var mesh = new Mesh(); ShallowCopy(mesh, src); return mesh; }
/// <summary> /// Gets the display name for a given mesh. /// /// Since meshes often are unnamed, this substitutes appropriate defaults /// and also adds a general "Mesh" prefix to visually separate them from nodes. /// </summary> /// <param name="mesh">Mesh</param> /// <param name="id">Mesh index</param> /// <returns></returns> private static string GetMeshDisplayName(Mesh mesh, int id) { return "Mesh " + (!string.IsNullOrEmpty(mesh.Name) ? ("\"" + mesh.Name + "\"") : id.ToString(CultureInfo.InvariantCulture)); }
public override void ApplyGhostMaterial(Mesh mesh, Material material, bool shaded) { }
public override void ApplyMaterial(Mesh mesh, Material mat, bool textured, bool shaded) { }
/// <summary> /// Finds the index of a mesh object. /// </summary> /// <param name="mesh"></param> /// <returns>Returns -1 if the mesh is not in the scene list of meshes.</returns> private int GetIndexForMesh(Mesh mesh) { int idx = _scene.Raw.Meshes.SkipWhile(m => m != mesh).Count(); return idx >= _scene.Raw.Meshes.Count ? -1 : idx; }
public static Mesh DeepCopy(Mesh src) { var mesh = new Mesh(); DeepCopy(mesh, src); return mesh; }
/// <summary> /// Draw a mesh using either its given material or a transparent "ghost" material. /// </summary> /// <param name="node">Current node</param> /// <param name="animated">Specifies whether animations should be played</param> /// <param name="showGhost">Indicates whether to substitute the mesh' material with a /// "ghost" surrogate material that allows looking through the geometry.</param> /// <param name="index">Mesh index in the scene</param> /// <param name="mesh">Mesh instance</param> /// <param name="flags"> </param> /// <returns></returns> protected override bool InternDrawMesh(Node node, bool animated, bool showGhost, int index, Mesh mesh, RenderFlags flags) { if (showGhost) { Owner.MaterialMapper.ApplyGhostMaterial(mesh, Owner.Raw.Materials[mesh.MaterialIndex], flags.HasFlag(RenderFlags.Shaded)); } else { Owner.MaterialMapper.ApplyMaterial(mesh, Owner.Raw.Materials[mesh.MaterialIndex], flags.HasFlag(RenderFlags.Textured), flags.HasFlag(RenderFlags.Shaded)); } if (GraphicsSettings.Default.BackFaceCulling) { GL.FrontFace(FrontFaceDirection.Ccw); GL.CullFace(CullFaceMode.Back); GL.Enable(EnableCap.CullFace); } else { GL.Disable(EnableCap.CullFace); } var hasColors = mesh.HasVertexColors(0); var hasTexCoords = mesh.HasTextureCoords(0); var skinning = mesh.HasBones && animated; foreach (var face in mesh.Faces) { BeginMode faceMode; switch (face.IndexCount) { case 1: faceMode = BeginMode.Points; break; case 2: faceMode = BeginMode.Lines; break; case 3: faceMode = BeginMode.Triangles; break; default: faceMode = BeginMode.Polygon; break; } GL.Begin(faceMode); for (var i = 0; i < face.IndexCount; i++) { var indice = face.Indices[i]; if (hasColors) { var vertColor = AssimpToOpenTk.FromColor(mesh.VertexColorChannels[0][indice]); GL.Color4(vertColor); } if (mesh.HasNormals) { Vector3 normal; if (skinning) { Skinner.GetTransformedVertexNormal(node, mesh, (uint)indice, out normal); } else { normal = AssimpToOpenTk.FromVector(mesh.Normals[indice]); } GL.Normal3(normal); } if (hasTexCoords) { var uvw = AssimpToOpenTk.FromVector(mesh.TextureCoordinateChannels[0][indice]); GL.TexCoord2(uvw.X, 1 - uvw.Y); } Vector3 pos; if (skinning) { Skinner.GetTransformedVertexPosition(node, mesh, (uint)indice, out pos); } else { pos = AssimpToOpenTk.FromVector(mesh.Vertices[indice]); } GL.Vertex3(pos); } GL.End(); } GL.Disable(EnableCap.CullFace); return skinning; }
/// <summary> /// Replace a given mesh with another when drawing. This has immediate effect. /// /// Editing tools use this to temporarily replace the mesh being rendered /// with a preview of the action. /// /// Pass null to revert to the original mesh. /// </summary> /// <param name="mesh"></param> /// <param name="overrideMesh"></param> public void SetOverrideMesh(Mesh mesh, Mesh overrideMesh) { _overrideMeshes[mesh] = overrideMesh; _nodesToShowChanged = true; }
private void SetMeshDetailDialogInfo(Mesh mesh, string text) { if (_meshDiag == null) { _meshDiag = new MeshDetailsDialog(); _meshDiag.FormClosed += (o, args) => { _meshDiag = null; }; _meshDiag.Show(); } else { _meshDiag.BringToFront(); } _meshDiag.SetMesh(FindForm() as MainWindow, mesh, text); }
private void AddMeshNode(Node owner, Mesh mesh, int id, TreeNode uiNode) { Debug.Assert(uiNode != null); Debug.Assert(mesh != null); // meshes need not be named, in this case we number them var desc = "Mesh " + (!string.IsNullOrEmpty(mesh.Name) ? ("\"" + mesh.Name + "\"") : id.ToString(CultureInfo.InvariantCulture)); var nod = new TreeNode(desc) { Tag = new KeyValuePair<Node, Mesh>(owner, mesh), ImageIndex = 3, SelectedImageIndex = 3, ContextMenuStrip = contextMenuStripMesh }; uiNode.Nodes.Add(nod); }
public static void ShallowCopy(Mesh dest, Mesh src) { GenericShallowCopy.Copy(dest, src); }
private SEASkeleton AppendSkeletonAnimation(Scene scene, Mesh mesh) { return null; }
/// <summary> /// Constructs a new Scene. /// </summary> /// <param name="scene">Unmanaged AiScene struct.</param> internal Scene(AiScene scene) { _flags = scene.Flags; //Read materials if(scene.NumMaterials > 0 && scene.Materials != IntPtr.Zero) { AiMaterial[] materials = MemoryHelper.MarshalArray<AiMaterial>(scene.Materials, (int) scene.NumMaterials, true); _materials = new Material[materials.Length]; for(int i = 0; i < _materials.Length; i++) { _materials[i] = new Material(materials[i]); } } //Read scenegraph if(scene.RootNode != IntPtr.Zero) { _rootNode = new Node(MemoryHelper.MarshalStructure<AiNode>(scene.RootNode), null); } //Read meshes if(scene.NumMeshes > 0 && scene.Meshes != IntPtr.Zero) { AiMesh[] meshes = MemoryHelper.MarshalArray<AiMesh>(scene.Meshes, (int) scene.NumMeshes, true); _meshes = new Mesh[meshes.Length]; for(int i = 0; i < _meshes.Length; i++) { _meshes[i] = new Mesh(meshes[i]); } } //Read lights if(scene.NumLights > 0 && scene.Lights != IntPtr.Zero) { AiLight[] lights = MemoryHelper.MarshalArray<AiLight>(scene.Lights, (int) scene.NumLights, true); _lights = new Light[lights.Length]; for(int i = 0; i < _lights.Length; i++) { _lights[i] = new Light(lights[i]); } } //Read cameras if(scene.NumCameras > 0 && scene.Cameras != IntPtr.Zero) { AiCamera[] cameras = MemoryHelper.MarshalArray<AiCamera>(scene.Cameras, (int) scene.NumCameras, true); _cameras = new Camera[cameras.Length]; for(int i = 0; i < _cameras.Length; i++) { _cameras[i] = new Camera(cameras[i]); } } //Read Textures if(scene.NumTextures > 0 && scene.Textures != IntPtr.Zero) { AiTexture[] textures = MemoryHelper.MarshalArray<AiTexture>(scene.Textures, (int) scene.NumTextures, true); _textures = new Texture[textures.Length]; for(int i = 0; i < _textures.Length; i++) { _textures[i] = Texture.CreateTexture(textures[i]); } } //Read animations if(scene.NumAnimations > 0 && scene.Animations != IntPtr.Zero) { AiAnimation[] animations = MemoryHelper.MarshalArray<AiAnimation>(scene.Animations, (int) scene.NumAnimations, true); _animations = new Animation[animations.Length]; for(int i = 0; i < _animations.Length; i++) { _animations[i] = new Animation(animations[i]); } } }
private SEASkeleton AppendSkeleton(Scene scene, Mesh mesh) { SEASkeleton skl = new SEASkeleton(GetValidString(modifiers, mesh.Name)); skl.joints = new List<JointData>(); foreach (Bone bone in mesh.Bones) { JointData jnt = new JointData(); jnt.name = bone.Name; jnt.parentIndex = -1; jnt.inverseBindMatrix = To3x4Array( bone.OffsetMatrix ); } modifiers.Add(skl); Writer.AddObject(skl); return skl; }
public Mesh GetOverrideMesh(Mesh mesh) { Mesh overrideMesh; if (_overrideMeshes.TryGetValue(mesh, out overrideMesh)) { return overrideMesh; } return null; }
/// <summary> /// Obtain the bone matrices for a given node mesh index at the /// current time. Calling this is costly, redundant invocations /// should thus be avoided. /// </summary> /// <param name="node">Node for which to query bone matrices</param> /// <param name="mesh">Mesh for which to query bone matrices. Must be /// one of the meshes attached to the node.</param> /// <returns>For each bone of the mesh the bone transformation /// matrix. The returned array is only valid for the rest of /// the frame or till the next call to GetBoneMatricesForMesh(). /// It may contain more entries than the mesh has bones, the extra entries /// should be ignored in this case.</returns> public Matrix4[] GetBoneMatricesForMesh(Node node, Mesh mesh) { Debug.Assert(node != null); Debug.Assert(mesh != null); // calculate the mesh's inverse global transform Matrix4 globalInverseMeshTransform; GetGlobalTransform( node, out globalInverseMeshTransform ); globalInverseMeshTransform.Invert(); // Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose // Therefore the formula is offsetMatrix * currentGlobalTransform * inverseCurrentMeshTransform for( int a = 0; a < mesh.BoneCount; ++a) { var bone = mesh.Bones[a]; Matrix4 currentGlobalTransform; GetGlobalTransform( bone.Name, out currentGlobalTransform ); _boneMatrices[a] = globalInverseMeshTransform * currentGlobalTransform * AssimpToOpenTk.FromMatrix(bone.OffsetMatrix); // TODO for some reason, all OpenTk matrices need a ^T - clarify our conventions somewhere _boneMatrices[a].Transpose(); } return _boneMatrices; }
private void AddMeshNode(Node owner, Mesh mesh, int id, TreeNode uiNode) { Debug.Assert(uiNode != null); Debug.Assert(mesh != null); // Meshes need not be named, in this case we number them var desc = GetMeshDisplayName(mesh, id); var key = new KeyValuePair<Node, Mesh>(owner, mesh); var newUiNode = new TreeNode(desc) { Tag = key, ImageIndex = 3, SelectedImageIndex = 3, ContextMenuStrip = contextMenuStripMesh }; uiNode.Nodes.Add(newUiNode); _treeNodesBySceneNodeMeshPair[key] = newUiNode; }