private void EvaluateNormals(IndexedMesh indexedMesh) { foreach (var bufferAndPrimitives in indexedMesh.GroupPrimitives()) { var bufferView = bufferAndPrimitives.BufferView; var existingNormals = bufferView.GetStream(StreamKey.Normal); if (existingNormals != null) { continue; } var positions = bufferView.GetStreamReader <Vector3>(StreamKey.Position); var normals = new ArrayMeshStream <Vector3>(positions.Count, StreamConverterFactory.Default); foreach (var primitive in bufferAndPrimitives) { primitive.SetIndexStream(StreamKey.Normal, primitive.GetIndexReader(StreamKey.Position).ToList()); } { foreach (var face in indexedMesh.Primitives.SelectMany(_ => _.GetFaces(StreamKey.Position))) { var a = positions[face.Item1]; var b = positions[face.Item2]; var c = positions[face.Item3]; var n = Vector3.Cross(b - a, c - a); normals[face.Item1] += n; normals[face.Item2] += n; normals[face.Item3] += n; } for (var index = 0; index < normals.Count; index++) { var normal = normals[index]; if (normal != Vector3.Zero) { normals[index] = Vector3.Normalize(normal); } } bufferView.SetStream(StreamKey.Normal, normals); } foreach (var primitive in bufferAndPrimitives) { primitive.SetIndexStream(StreamKey.Normal, primitive.GetIndexReader(StreamKey.Position).ToList()); } } }
private IEnumerable <IMesh> PaintSingleStreamMesh(GpuMesh mesh) { foreach (var bufferAndPrimitives in mesh.GroupPrimitives()) { var bufferView = bufferAndPrimitives.BufferView; if (bufferView.GetStream(StreamKey.Color) != null) { continue; } var meshStream = bufferView.GetStream(StreamKey.Position); var streamConverterFactory = meshStream.ConverterFactory; var colors = new Vector4[meshStream.Count]; new Span <Vector4>(colors).Fill(_color); var arrayMeshStream = new ArrayMeshStream <Vector4>(colors, streamConverterFactory); bufferView.SetStream(StreamKey.Color, arrayMeshStream); } yield return(mesh); }
private IMeshStream CreateMeshStream(ISource source, string semantic) { var floatArray = source as FloatArraySource; if (floatArray != null) { bool swapY = (semantic == Streams.TexCoord); if (source.GetStride() == 3) { var arrayMeshStream = new ArrayMeshStream<Float3>(source.GetCount(), streamConverterFactory); for (int i = 0; i < arrayMeshStream.Count; ++i) { var y = floatArray[i * 3 + 1]; if (swapY) y = 1.0f - y; arrayMeshStream[i] = new Float3(floatArray[i * 3 + 0], y, floatArray[i * 3 + 2]); } return arrayMeshStream; } else if (source.GetStride() == 2) { var arrayMeshStream = new ArrayMeshStream<Float2>(source.GetCount(), streamConverterFactory); for (int i = 0; i < arrayMeshStream.Count; ++i) { var y = floatArray[i * 2 + 1]; if (swapY) y = 1.0f - y; arrayMeshStream[i] = new Float2(floatArray[i * 2 + 0], y); } return arrayMeshStream; } else if (source.GetStride() == 4) { var arrayMeshStream = new ArrayMeshStream<Float4>(source.GetCount(), streamConverterFactory); for (int i = 0; i < arrayMeshStream.Count; ++i) { var y = floatArray[i * 4 + 1]; if (swapY) y = 1.0f - y; arrayMeshStream[i] = new Float4(floatArray[i * 4 + 0], y, floatArray[i * 4 + 2], floatArray[i * 4 + 3]); } return arrayMeshStream; } } else { throw new NotImplementedException(); } throw new NotImplementedException(); }
private void ParsSubMesh(AseParser parser, Scene scene, Node node) { var mesh = new SeparateStreamsMesh(); var submesh = mesh.CreateSubmesh(); node.Mesh = mesh; scene.Geometries.Add(mesh); ArrayMeshStream<Float3> vertices = null; ListMeshStream<Float3> normalStream = null; FaceNormal[] normals = null; ArrayMeshStream<Float3> tvertices = null; ArrayMeshStream<Color> cols = null; AseFace[] faces = null; AseTFace[] tfaces = null; Tuple<int, int, int>[] colFaces = null; //TODO: submesh can have it's own vertex streams parser.Consume("{"); for (;;) { var attr = parser.Consume(); if (attr == null || attr == "}") { break; } if (0 == string.Compare(attr, "*TIMEVALUE", StringComparison.InvariantCultureIgnoreCase)) { parser.ConsumeFloat(); continue; } if (0 == string.Compare(attr, "*MESH_NUMVERTEX", StringComparison.InvariantCultureIgnoreCase)) { vertices = new ArrayMeshStream<Float3>(parser.ConsumeInt(), converterFactory); mesh.SetStream(Streams.Position, 0, vertices); continue; } if (0 == string.Compare(attr, "*MESH_VERTEX_LIST", StringComparison.InvariantCultureIgnoreCase)) { this.ParseVertexList(parser, vertices); continue; } if (0 == string.Compare(attr, "*MESH_NUMTVERTEX", StringComparison.InvariantCultureIgnoreCase)) { tvertices = new ArrayMeshStream<Float3>(parser.ConsumeInt(), converterFactory); mesh.SetStream(Streams.TexCoord, 0, tvertices); continue; } if (0 == string.Compare(attr, "*MESH_TVERTLIST", StringComparison.InvariantCultureIgnoreCase)) { this.ParseTVertList(parser, tvertices); continue; } if (0 == string.Compare(attr, "*MESH_NUMTVFACES", StringComparison.InvariantCultureIgnoreCase)) { tfaces = new AseTFace[parser.ConsumeInt()]; continue; } if (0 == string.Compare(attr, "*MESH_TFACELIST", StringComparison.InvariantCultureIgnoreCase)) { this.ParseTFaceList(parser, tfaces); continue; } if (0 == string.Compare(attr, "*MESH_NUMCVERTEX", StringComparison.InvariantCultureIgnoreCase)) { cols = new ArrayMeshStream<Color>(parser.ConsumeInt(), converterFactory); mesh.SetStream(Streams.Color, 0, cols); continue; } if (0 == string.Compare(attr, "*MESH_CVERTLIST", StringComparison.InvariantCultureIgnoreCase)) { this.ParseColList(parser, cols); continue; } if (0 == string.Compare(attr, "*MESH_NUMCVFACES", StringComparison.InvariantCultureIgnoreCase)) { colFaces = new Tuple<int, int, int>[parser.ConsumeInt()]; continue; } if (0 == string.Compare(attr, "*MESH_CFACELIST", StringComparison.InvariantCultureIgnoreCase)) { this.ParseColFaceList(parser, colFaces); continue; } if (0 == string.Compare(attr, "*MESH_NORMALS", StringComparison.InvariantCultureIgnoreCase)) { normals = new FaceNormal[faces.Length]; this.ParsNormalList(parser, normals); continue; } if (0 == string.Compare(attr, "*MESH_NUMFACES", StringComparison.InvariantCultureIgnoreCase)) { faces = new AseFace[parser.ConsumeInt()]; continue; } if (0 == string.Compare(attr, "*MESH_FACE_LIST", StringComparison.InvariantCultureIgnoreCase)) { this.ParseFaceList(parser, faces); continue; } parser.UnknownLexemError(); } ListMeshStream<int> positionIndices = null; if (vertices != null) { positionIndices = new ListMeshStream<int>(faces.Length * 3,converterFactory); submesh.SetIndexStream(Streams.Position, 0, positionIndices); } ListMeshStream<int> normalIndices = null; if (normals != null) { normalStream = new ListMeshStream<Float3>(faces.Length * 3, converterFactory); mesh.SetStream(Streams.Normal, 0, normalStream); normalIndices = new ListMeshStream<int>(faces.Length * 3, converterFactory); submesh.SetIndexStream(Streams.Normal, 0, normalIndices); } ListMeshStream<int> colorIndices = null; if (cols != null) { colorIndices = new ListMeshStream<int>(faces.Length * 3, converterFactory); submesh.SetIndexStream(Streams.Color, 0, colorIndices); } ListMeshStream<int> texCoordIndices = null; if (tvertices != null) { texCoordIndices = new ListMeshStream<int>(faces.Length * 3, converterFactory); submesh.SetIndexStream(Streams.TexCoord, 0, texCoordIndices); } for (int i = 0; i < faces.Length; ++i) { // -------------------------------------------------- // if (positionIndices != null) { positionIndices.Add(faces[i].A); } if (normalIndices != null) { normalIndices.Add(normalStream.Count); normalStream.Add(normals[i].A.Normal); } if (colorIndices != null) { colorIndices.Add(colFaces[i].Item1); } if (texCoordIndices != null) { texCoordIndices.Add(tfaces[i].A); } // -------------------------------------------------- // if (positionIndices != null) { positionIndices.Add(faces[i].C); } if (normalIndices != null) { normalIndices.Add(normalStream.Count); normalStream.Add(normals[i].C.Normal); } if (colorIndices != null) { colorIndices.Add(colFaces[i].Item3); } if (texCoordIndices != null) { texCoordIndices.Add(tfaces[i].C); } // -------------------------------------------------- // if (positionIndices != null) { positionIndices.Add(faces[i].B); } if (normalIndices != null) { normalIndices.Add(normalStream.Count); normalStream.Add(normals[i].B.Normal); } if (colorIndices != null) { colorIndices.Add(colFaces[i].Item2); } if (texCoordIndices != null) { texCoordIndices.Add(tfaces[i].B); } // -------------------------------------------------- // } }