Example #1
0
 public StudioModel(string name, uint crc, StudioFile studioFile)
 //TODO: figure out if models have a preset size
     : base(name, crc, Vector3.Zero, Vector3.Zero)
 {
     StudioFile = studioFile ?? throw new ArgumentNullException(nameof(studioFile));
 }
 public unsafe Matrix4x4[] SetUpBones(StudioFile studioFile, double currentTime, uint sequenceIndex, float lastTime, float frame, float frameRate, in BoneData boneData)
        private static SubModelData InternalCreateSubModel(StudioFile studioFile, BodyModel subModel, List <StudioVertex> vertices, List <uint> indices)
        {
            var meshes = new List <MeshData>(subModel.Meshes.Count);

            //Add all vertices to the list
            foreach (var mesh in subModel.Meshes)
            {
                //Use the first skin family for reference
                //The compiler also uses this to calculate the s and t values
                var texture = studioFile.Textures[studioFile.Skins[0][mesh.Skin]];

                var firstIndex = indices.Count;

                var i = 0;

                for (int command = mesh.TriangleCommands[i]; command != 0; command = mesh.TriangleCommands[i])
                {
                    ++i;

                    //Commands come in sets of 4 values:
                    //Vertex index
                    //Normal index, also chrome index for chrome textures
                    //Texture s coord
                    //Texture t coord

                    //Negative values are fans, positive values are strips
                    //TODO: handle chrome
                    var isFan = command < 0;

                    if (isFan)
                    {
                        command = -command;
                    }

                    var firstVertex = vertices.Count;

                    for (var verticesLeft = command; verticesLeft > 0; --verticesLeft, i += 4)
                    {
                        var vertexIndex = mesh.TriangleCommands[i];
                        var normalIndex = mesh.TriangleCommands[i + 1];
                        var sCoord      = mesh.TriangleCommands[i + 2];
                        var tCoord      = mesh.TriangleCommands[i + 3];

                        vertices.Add(new StudioVertex
                        {
                            WorldTexture = new WorldTextureCoordinate
                            {
                                Vertex  = subModel.Vertices[vertexIndex].Vertex,
                                Texture = new Vector2((float)(sCoord / (double)texture.Width), (float)(tCoord / (double)texture.Height))
                            },
                            Normal          = subModel.Normals[normalIndex].Normal,
                            VertexBoneIndex = subModel.Vertices[vertexIndex].Bone,
                            NormalBoneIndex = subModel.Normals[normalIndex].Bone,
                        });
                    }

                    var trianglesToAdd = command - 2;

                    if (isFan)
                    {
                        for (var triangle = 0; triangle < trianglesToAdd; ++triangle)
                        {
                            indices.Add((uint)firstVertex);
                            indices.Add((uint)(firstVertex + triangle + 1));
                            indices.Add((uint)(firstVertex + triangle + 2));
                        }
                    }
                    else
                    {
                        for (var triangle = 0; triangle < trianglesToAdd; ++triangle)
                        {
                            //Every other triangle is inverted because strips normally do that internally
                            if ((triangle % 2) == 0)
                            {
                                indices.Add((uint)firstVertex);
                                indices.Add((uint)(firstVertex + 1));
                                indices.Add((uint)(firstVertex + 2));
                            }
                            else
                            {
                                indices.Add((uint)(firstVertex + 2));
                                indices.Add((uint)(firstVertex + 1));
                                indices.Add((uint)firstVertex);
                            }

                            ++firstVertex;
                        }
                    }
                }

                meshes.Add(new MeshData
                {
                    Mesh         = mesh,
                    StartIndex   = (uint)firstIndex,
                    IndicesCount = (uint)(indices.Count - firstIndex)
                });
            }

            return(new SubModelData
            {
                Meshes = meshes.ToArray()
            });
        }