/// <summary> /// Thread to animate the model. /// </summary> private void _animation() { Rsm rsm = new Rsm(_baseLoadData[3]); this.Dispatch(delegate { _slider.Maximum = rsm.AnimationLength; }); foreach (var mesh in rsm.Meshes) { Console.WriteLine(mesh.Name); } while (!_terminateThread) { _mainModelGroup.Dispatch(delegate { _mainModelGroup.Children.Clear(); LoadModel(rsm, _mainModelGroup); }); if (_animationStartState == "++") { _animationFrame++; } if (_animationFrame >= rsm.AnimationLength) { _animationFrame = 0; } int delay = (int)(1000 / rsm.FrameRatePerSecond); if (delay < 5) { delay = 33; } Thread.Sleep(delay); } }
public TextureMeshComparer2(Rsm rsm, Vertex origin) { _rsm = rsm; _origin = origin; }
private void LoadModel(Rsm rsm, Model3DGroup mainModel3DGroup) { rsm.MainMesh.Calc(_animationFrame); rsm.ClearBuffers(); List <MeshRawData2> meshData = new List <MeshRawData2>(); List <Vertex> position = new List <Vertex>(); // Convert all data to WPF 3D, calculate normals, texture effects, etc foreach (var mesh in rsm.Meshes) { if (_baseLoadData.Length > 4) { if (!_baseLoadData[4].Contains(mesh.Name)) { continue; } } var vertices = _compile(mesh); Dictionary <string, MeshRawData2> allRawData = new Dictionary <string, MeshRawData2>(); List <Vector3D> normals = new List <Vector3D>(vertices.Count); List <Vector3D> vertices3d = new List <Vector3D>(vertices.Count); List <Point3D> verticesPoints3D = new List <Point3D>(vertices.Count); List <Point> textures3D = new List <Point>(mesh.TextureVertices.Count); for (int i = 0; i < vertices.Count; i++) { normals.Add(new Vector3D(0, 0, 0)); vertices3d.Add(new Vector3D(vertices[i].X, vertices[i].Y, vertices[i].Z)); verticesPoints3D.Add(new Point3D(vertices[i].X, vertices[i].Y, vertices[i].Z)); } for (int i = 0; i < mesh.TextureVertices.Count; i++) { textures3D.Add(new Point(mesh.TextureVertices[i].U, mesh.TextureVertices[i].V)); } // Could use the smoothing groups, but... this is much simpler and good enough. for (int i = 0; i < mesh.Faces.Count; i++) { Vector3D p = Vector3D.CrossProduct(vertices3d[mesh.Faces[i].VertexIds[1]] - vertices3d[mesh.Faces[i].VertexIds[0]], vertices3d[mesh.Faces[i].VertexIds[2]] - vertices3d[mesh.Faces[i].VertexIds[0]]); normals[mesh.Faces[i].VertexIds[0]] += p; normals[mesh.Faces[i].VertexIds[1]] += p; normals[mesh.Faces[i].VertexIds[2]] += p; } for (int i = 0; i < normals.Count; i++) { normals[i].Normalize(); } for (int i = 0; i < mesh.Faces.Count; i++) { var face = mesh.Faces[i]; string texture; if (mesh.Textures.Count > 0) { texture = mesh.Textures[mesh.TextureIndexes[face.TextureId]]; } else { texture = rsm.Textures[mesh.TextureIndexes[face.TextureId]]; } if (!allRawData.ContainsKey(texture)) { allRawData[texture] = new MeshRawData2 { Texture = texture, Alpha = 0, Position = mesh.BoundingBox.Center, Mesh = mesh, BoundingBox = mesh.BoundingBox }; } var rawData = allRawData[texture]; rawData.Positions.Add(verticesPoints3D[face.VertexIds[0]]); rawData.Positions.Add(verticesPoints3D[face.VertexIds[1]]); rawData.Positions.Add(verticesPoints3D[face.VertexIds[2]]); rawData.Normals.Add(normals[face.VertexIds[0]]); rawData.Normals.Add(normals[face.VertexIds[1]]); rawData.Normals.Add(normals[face.VertexIds[2]]); Point v0 = textures3D[face.TextureVertexIds[0]]; Point v1 = textures3D[face.TextureVertexIds[1]]; Point v2 = textures3D[face.TextureVertexIds[2]]; if (mesh.TextureKeyFrameGroup.Count > 0) { foreach (var type in mesh.TextureKeyFrameGroup.Types) { if (mesh.TextureKeyFrameGroup.HasTextureAnimation(face.TextureId, type)) { float offset = mesh.GetTexture(_animationFrame, face.TextureId, type); Matrix4 mat = Matrix4.Identity; switch (type) { case 0: v0.X += offset; v1.X += offset; v2.X += offset; break; case 1: v0.Y += offset; v1.Y += offset; v2.Y += offset; break; case 2: v0.X *= offset; v1.X *= offset; v2.X *= offset; break; case 3: v0.Y *= offset; v1.Y *= offset; v2.Y *= offset; break; case 4: mat = Matrix4.Rotate3(mat, new Vertex(0, 0, 1), offset); Vertex n0 = Matrix4.Multiply2(mat, new Vertex(v0.X, v0.Y, 0)); Vertex n1 = Matrix4.Multiply2(mat, new Vertex(v1.X, v1.Y, 0)); Vertex n2 = Matrix4.Multiply2(mat, new Vertex(v2.X, v2.Y, 0)); v0.X = n0.X; v0.Y = n0.Y; v1.X = n1.X; v1.Y = n1.Y; v2.X = n2.X; v2.Y = n2.Y; rawData.MaterialNoTile = true; break; } } } } rawData.TextureCoordinates.Add(v0); rawData.TextureCoordinates.Add(v1); rawData.TextureCoordinates.Add(v2); } foreach (var meshRawData in allRawData) { meshData.Add(meshRawData.Value); position.Add(mesh.Position_); } } for (int i = 0; i < meshData.Count; i++) { meshData[i].Material = _generateMaterial(meshData[i].Texture, meshData[i].MaterialNoTile); } meshData.Sort(new TextureMeshComparer2(rsm, new Vertex(_cameraPosition.X, _cameraPosition.Y, _cameraPosition.Z))); foreach (var meshRawData in meshData) { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions = new Point3DCollection(meshRawData.Positions); mesh.TextureCoordinates = new PointCollection(meshRawData.TextureCoordinates); mesh.Normals = new Vector3DCollection(meshRawData.Normals); var material = meshRawData.Material; GeometryModel3D model = new GeometryModel3D(mesh, material); model.BackMaterial = material; mainModel3DGroup.Children.Add(model); } DrawGrid(); Matrix3D mat3d = Matrix3D.Identity; mat3d.Scale(new Vector3D(-1, 1, 1)); MatrixTransform3D mt = new MatrixTransform3D(mat3d); mainModel3DGroup.Transform = mt; _modelGrid.Content.Transform = mt; }