예제 #1
0
        /// <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);
            }
        }
예제 #2
0
 public TextureMeshComparer2(Rsm rsm, Vertex origin)
 {
     _rsm    = rsm;
     _origin = origin;
 }
예제 #3
0
        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;
        }