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() }); }