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; } }
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(); }
private void Construct(Assimp.Mesh mesh, Action <Vector3, Vector3, Vector2> appendVertex, Action <Int3> appendIndex, ref int offset) { if (mesh.HasFaces && mesh.HasVertices) { for (int i = 0; i < mesh.VertexCount; i++) { Vector3D mp = mesh.Vertices[i]; Vector3 p = new Vector3(mp.X, mp.Y, mp.Z); Vector3D mn = mesh.Normals[i]; Vector3 n = new Vector3(mn.X, mn.Y, mn.Z); appendVertex(p, n, Vector2.Zero); } int[] inds = mesh.GetIntIndices(); for (int i = 0; i < inds.Length / 3; i++) { appendIndex(new Int3(inds[i * 3 + offset], inds[i * 3 + offset + 1], inds[i * 3 + offset + 2])); } offset += mesh.VertexCount; } }
private ModelData.MeshPart Process(ModelData.Mesh mesh, Assimp.Mesh assimpMesh) { var meshPart = new ModelData.MeshPart() { MaterialIndex = assimpMesh.MaterialIndex, VertexBufferRange = new ModelData.BufferRange() { Slot = mesh.VertexBuffers.Count }, IndexBufferRange = new ModelData.BufferRange() { Slot = mesh.IndexBuffers.Count } }; var vertexBuffer = new ModelData.VertexBuffer() { Layout = new List <VertexElement>() }; mesh.VertexBuffers.Add(vertexBuffer); var indexBuffer = new ModelData.IndexBuffer(); mesh.IndexBuffers.Add(indexBuffer); var layout = vertexBuffer.Layout; int vertexBufferElementSize = 0; // Add position layout.Add(VertexElement.PositionTransformed(Format.R32G32B32_Float, 0)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>(); // Add normals if (assimpMesh.HasNormals) { layout.Add(VertexElement.Normal(0, Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>(); } // Add colors if (assimpMesh.VertexColorChannelCount > 0) { for (int localIndex = 0, i = 0; i < assimpMesh.VertexColorChannelCount; i++) { if (assimpMesh.HasVertexColors(i)) { layout.Add(VertexElement.Color(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Color4>(); localIndex++; } } } // Add textures if (assimpMesh.TextureCoordsChannelCount > 0) { for (int localIndex = 0, i = 0; i < assimpMesh.TextureCoordsChannelCount; i++) { if (assimpMesh.HasTextureCoords(i)) { var uvCount = assimpMesh.GetUVComponentCount(i); if (uvCount == 2) { layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32_Float, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector2>(); } else if (uvCount == 3) { layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>(); } else { throw new InvalidOperationException("Unexpected uv count"); } localIndex++; } } } // Add tangent / bitangent if (assimpMesh.HasTangentBasis) { layout.Add(VertexElement.Tangent(Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>(); layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>(); } // Extract Skinning Indices / Weights bool hasWeights = false; var skinningCount = new int[assimpMesh.VertexCount]; var skinningIndices = new Int4[assimpMesh.VertexCount]; var skinningWeights = new Vector4[assimpMesh.VertexCount]; if (assimpMesh.HasBones) { meshPart.BoneOffsetMatrices = new Matrix[assimpMesh.BoneCount]; for (int i = 0; i < assimpMesh.Bones.Length; i++) { var bone = assimpMesh.Bones[i]; meshPart.BoneOffsetMatrices[i] = ConvertMatrix(bone.OffsetMatrix); if (bone.HasVertexWeights) { var boneNode = scene.RootNode.FindNode(bone.Name); var boneIndex = skinnedBones[boneNode]; for (int j = 0; j < bone.VertexWeightCount; j++) { var weights = bone.VertexWeights[j]; var vertexSkinningCount = skinningCount[weights.VertexID]; skinningIndices[weights.VertexID][vertexSkinningCount] = boneIndex; skinningWeights[weights.VertexID][vertexSkinningCount] = weights.Weight; skinningCount[weights.VertexID] = ++vertexSkinningCount; } hasWeights = true; } } if (hasWeights) { layout.Add(VertexElement.BlendIndices(Format.R16G16B16A16_SInt, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Int4>(); layout.Add(VertexElement.BlendWeights(Format.R32G32B32A32_Float, vertexBufferElementSize)); vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector4>(); } } // Write all vertices meshPart.VertexBufferRange.Count = assimpMesh.VertexCount; vertexBuffer.Count = assimpMesh.VertexCount; vertexBuffer.Buffer = new byte[vertexBufferElementSize * assimpMesh.VertexCount]; // 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); for (int i = 0; i < assimpMesh.VertexCount; i++) { var position = assimpMesh.Vertices[i]; vertexStream.Write(position); // Store bounding points for BoundingSphere pre-calculation boundingPoints[currentBoundingPointIndex++] = new Vector3(position.X, position.Y, position.Z); // Add normals if (assimpMesh.HasNormals) { vertexStream.Write(assimpMesh.Normals[i]); } // Add colors if (assimpMesh.VertexColorChannelCount > 0) { for (int j = 0; j < assimpMesh.VertexColorChannelCount; j++) { if (assimpMesh.HasVertexColors(j)) { vertexStream.Write(assimpMesh.GetVertexColors(j)[i]); } } } // Add textures if (assimpMesh.TextureCoordsChannelCount > 0) { for (int j = 0; j < assimpMesh.TextureCoordsChannelCount; j++) { if (assimpMesh.HasTextureCoords(j)) { var uvCount = assimpMesh.GetUVComponentCount(j); var uv = assimpMesh.GetTextureCoords(j)[i]; if (uvCount == 2) { vertexStream.Write(new Vector2(uv.X, uv.Y)); } else { vertexStream.Write(uv); } } } } // Add tangent / bitangent if (assimpMesh.HasTangentBasis) { vertexStream.Write(assimpMesh.Tangents[i]); vertexStream.Write(assimpMesh.BiTangents[i]); } // Add Skinning Indices/Weights if (assimpMesh.HasBones && hasWeights) { vertexStream.Write(skinningIndices[i]); vertexStream.Write(skinningWeights[i]); } } vertexStream.Dispose(); // 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; } return(meshPart); }