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(); }
void WriteVertices(Mesh assimpMesh, ModelData.MeshPart meshPart, ModelData.VertexBuffer vertexBuffer, int vertexBufferElementSize) { // 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) { if (!options.ExcludeElements.Contains("Tangent")) { double w = Vector3D.Dot(assimpMesh.Normals[i], Vector3D.Cross(assimpMesh.Tangents[i], assimpMesh.Tangents[i])); Vector3D t = assimpMesh.Tangents[i]; Vector4 t4D = new Vector4(t.X, t.Y, t.Z, (float)w); vertexStream.Write(t4D); } if (!options.ExcludeElements.Contains("BiTangent")) { vertexStream.Write(assimpMesh.BiTangents[i]); } } } vertexStream.Dispose(); }
private ModelData.MeshPart Process(ModelData.Mesh mesh, Mesh assimpMesh) { var meshPart = new ModelData.MeshPart { PrimitiveTopology = PrimitiveTopology.TriangleList, 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 += SharpDX.Utilities.SizeOf <Vector3>(); // Add normals if (assimpMesh.HasNormals) { layout.Add(VertexElement.Normal(0, Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>(); } // Add colors if (assimpMesh.VertexColorChannelCount > 0) { for (int localIndex = 0, i = 0; i < assimpMesh.VertexColorChannelCount; i++) { if (assimpMesh.HasVertexColors(i)) { layout.Add(VertexElement.Normal(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize)); vertexBufferElementSize += SharpDX.Utilities.SizeOf <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 += SharpDX.Utilities.SizeOf <Vector2>(); } else if (uvCount == 3) { layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>(); } else { throw new InvalidOperationException("Unexpected uv count"); } localIndex++; } } } if (options.ModelOperations.HasFlag(ModelOperation.CalculateBarycentricCoordinates)) { layout.Add(new VertexElement("BARYCENTRIC", 0, Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>(); } else // Add tangent / bitangent if (assimpMesh.HasTangentBasis) { if (!options.ExcludeElements.Contains("Tangent")) { layout.Add(VertexElement.Tangent(Format.R32G32B32A32_Float, vertexBufferElementSize)); vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector4>(); } if (!options.ExcludeElements.Contains("BiTangent")) { layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize)); vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>(); } } if (options.ModelOperations.HasFlag(ModelOperation.CalculateBarycentricCoordinates)) { WriteBarycentricVertices(assimpMesh, meshPart, vertexBuffer, vertexBufferElementSize); } else { WriteVertices(assimpMesh, meshPart, vertexBuffer, vertexBufferElementSize); } WriteIndices(assimpMesh, meshPart, indexBuffer); return(meshPart); }