/// <summary> /// Creates a new empty vertex attribute using the default struct setups /// </summary> /// <param name="attributeType">The attribute type of the vertex attribute</param> public GCVertexSet(GCVertexAttribute attributeType) { attribute = attributeType; switch (attribute) { case GCVertexAttribute.Position: dataType = GCDataType.Float32; structType = GCStructType.Position_XYZ; break; case GCVertexAttribute.Normal: dataType = GCDataType.Float32; structType = GCStructType.Normal_XYZ; break; case GCVertexAttribute.Color0: dataType = GCDataType.RGBA8; structType = GCStructType.Color_RGBA; break; case GCVertexAttribute.Tex0: dataType = GCDataType.Signed16; structType = GCStructType.TexCoord_ST; break; default: throw new ArgumentException($"Datatype { attribute } is not a valid vertex type for SA2"); } data = new List <IOVtx>(); }
/// <summary> /// Create a custom empty vertex attribute /// </summary> /// <param name="attribute"></param> /// <param name="dataType"></param> /// <param name="structType"></param> /// <param name="fractionalBitCount"></param> public GCVertexSet(GCVertexAttribute attribute, GCDataType dataType, GCStructType structType) { this.attribute = attribute; this.dataType = dataType; this.structType = structType; data = new List <IOVtx>(); }
/// <summary> /// Creates a new parameter with the default value according to each attribute type <br/> (which are the only ones that work ingame) /// </summary> /// <param name="vertexAttrib">The vertex attribute type that the parameter is for</param> public VtxAttrFmtParameter(GCVertexAttribute vertexAttrib) : base(ParameterType.VtxAttrFmt) { VertexAttribute = vertexAttrib; // Setting the default values switch (vertexAttrib) { case GCVertexAttribute.Position: Unknown = 5120; break; case GCVertexAttribute.Normal: Unknown = 9216; break; case GCVertexAttribute.Color0: Unknown = 27136; break; case GCVertexAttribute.Tex0: Unknown = 33544; break; default: break; } }
/// <summary> /// Read an entire vertex data set /// </summary> /// <param name="file">The files contents</param> /// <param name="address">The starting address of the file</param> /// <param name="imageBase">The image base of the addresses</param> public GCVertexSet(byte[] file, uint address, uint imageBase) { attribute = (GCVertexAttribute)file[address]; if (attribute == GCVertexAttribute.Null) { return; } uint structure = ByteConverter.ToUInt32(file, (int)address + 4); structType = (GCStructType)(structure & 0x0F); dataType = (GCDataType)((structure >> 4) & 0x0F); if (file[address + 1] != StructSize) { throw new Exception($"Read structure size doesnt match calculated structure size: {file[address + 1]} != {StructSize}"); } // reading the data int count = ByteConverter.ToUInt16(file, (int)address + 2); int tmpaddr = (int)(ByteConverter.ToUInt32(file, (int)address + 8) - imageBase); data = new List <IOVtx>(); switch (attribute) { case GCVertexAttribute.Position: case GCVertexAttribute.Normal: for (int i = 0; i < count; i++) { data.Add(new Vector3(file, tmpaddr)); tmpaddr += 12; } break; case GCVertexAttribute.Color0: for (int i = 0; i < count; i++) { data.Add(new Color(file, tmpaddr, dataType, out tmpaddr)); } break; case GCVertexAttribute.Tex0: for (int i = 0; i < count; i++) { data.Add(new UV(file, tmpaddr)); tmpaddr += 4; } break; default: throw new ArgumentException($"Attribute type not valid sa2 type: {attribute}"); } }
/// <summary> /// Allows to manually create a Vertex attribute parameter /// </summary> /// <param name="Unknown"></param> /// <param name="vertexAttrib">The vertex attribute type that the parameter is for</param> public VtxAttrFmtParameter(ushort Unknown, GCVertexAttribute vertexAttrib) : base(ParameterType.VtxAttrFmt) { this.Unknown = Unknown; VertexAttribute = vertexAttrib; }