private static GenericMesh ReadMesh(DataReader r, uint infoOffset, uint bufferOffset) { GenericMesh mesh = new GenericMesh(); var meshEntry = r.ReadStruct <Entry>(); if (meshEntry.ID == 4) { r.Seek(infoOffset + meshEntry.Offset); var lodCount = r.ReadInt32(); r.Seek(infoOffset + meshEntry.Offset + 0x10); r.PrintPosition(); var indexEntryIndex = r.ReadUInt32(); r.Seek(0x30 + indexEntryIndex * 0x10); var indexInfoEntry = r.ReadStruct <Entry>(); r.Seek(infoOffset + indexInfoEntry.Offset + 4); var indexBufferEntryIndex = r.ReadUInt32(); r.Seek(0x30 + indexBufferEntryIndex * 0x10); var indexBufferEntry = r.ReadStruct <Entry>(); r.Seek(infoOffset + indexBufferEntry.Offset); r.PrintPosition(); var indexDataBufferEntry = r.ReadStruct <Entry>(); if (indexBufferEntry.Flags == 0x010A || lodCount > 1) { return(null); } r.Seek(bufferOffset + indexDataBufferEntry.Offset); for (uint j = 0; j < indexDataBufferEntry.Size / 0x20; j++) { GenericVertex v = new GenericVertex(); v.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.Skip(0x14); mesh.Vertices.Add(v); mesh.Triangles.Add(j); } Console.WriteLine(meshEntry.Hash.ToString("X") + " " + meshEntry.ID); Console.WriteLine("\t" + lodCount + " " + indexBufferEntry.Flags.ToString("X") + " " + (bufferOffset + indexDataBufferEntry.Offset).ToString("X")); /*r.Seek(infoOffset + meshEntry.Offset + 0x30); * var vertexEntryIndex = r.ReadUInt32(); * * r.Seek(0x30 + vertexEntryIndex * 0x10 + 0x08); * var vertexBufferEntryIndex = r.ReadUInt32(); * * r.Seek(0x30 + indexBufferEntryIndex * 0x10); * r.Seek(0x30 + indexBufferEntryIndex * 0x10);*/ return(mesh); } return(null); }
public static void SetVisited <VertexT, EdgeT, GraphT>(this GenericVertex <VertexT, EdgeT, GraphT> v, bool visitedOrNot) where VertexT : GenericVertex <VertexT, EdgeT, GraphT> where EdgeT : GenericEdge <VertexT, EdgeT, GraphT> where GraphT : GenericGraph <VertexT, EdgeT, GraphT> { v.Flags[(int)GenericVertex <VertexT, EdgeT, GraphT> .VertexFlags.VertexFlags_Visited] = visitedOrNot; }
private static string WriteWeights(GenericVertex v) { StringBuilder o = new StringBuilder(); int Count = 0; if (v.Weights.X != 0) { Count++; o.Append($"{v.Bones.X} {v.Weights.X} "); } if (v.Weights.Y != 0) { Count++; o.Append($"{v.Bones.Y} {v.Weights.Y} "); } if (v.Weights.Z != 0) { Count++; o.Append($"{v.Bones.Z} {v.Weights.Z} "); } if (v.Weights.W != 0) { Count++; o.Append($"{v.Bones.W} {v.Weights.W} "); } return(Count + " " + o.ToString()); }
public static GenericVertex[] GetAccelDecor(RedLine line) { var linecolor = Constants.RedLineColor; var multiplier = ((RedLine)line).Multiplier; GenericVertex[] ret = new GenericVertex[3 * multiplier]; var angle = Angle.FromLine(line.End, line.Start); var angle2 = Angle.FromRadians(angle.Radians - 1.5708f); var start = line.Position2; for (int idx = 0; idx < multiplier; idx++) { var a = start; var b = angle.MovePoint(start, line.inv ? -8 : 8); var c = angle2.MovePoint(b, 8); ret[idx * 3 + 0] = new GenericVertex((Vector2)a, linecolor); ret[idx * 3 + 1] = new GenericVertex((Vector2)b, linecolor); ret[idx * 3 + 2] = new GenericVertex((Vector2)c, linecolor); if (idx + 1 < multiplier) { start = angle.MovePoint(start, line.inv ? -2 : 2); } } return(ret); }
public static bool IsVisited <VertexT, EdgeT, GraphT>(this GenericVertex <VertexT, EdgeT, GraphT> v) where VertexT : GenericVertex <VertexT, EdgeT, GraphT> where EdgeT : GenericEdge <VertexT, EdgeT, GraphT> where GraphT : GenericGraph <VertexT, EdgeT, GraphT> { return(v.Flags[(int)GenericVertex <VertexT, EdgeT, GraphT> .VertexFlags.VertexFlags_Visited]); }
public void Initialize(AutoArray <GameLine> lines) { Clear(); ResourceSync initsync = new ResourceSync(); GenericVertex[] vertices = new GenericVertex[lines.Count * wellsize]; System.Threading.Tasks.Parallel.For(0, lines.Count, (idx) => { var line = (StandardLine)lines[idx]; var well = GetWell(line); for (int i = 0; i < wellsize; i++) { vertices[idx * wellsize + i] = well[i]; } try { initsync.UnsafeEnterWrite(); _lines.Add(line.ID, idx * wellsize); } finally { initsync.UnsafeExitWrite(); } }); _vertexcounter = vertices.Length; _vbo.Bind(); EnsureVBOSize(vertices.Length, false); _vbo.SetData(vertices, 0, 0, vertices.Length); _vbo.Unbind(); }
private List <GenericVertex> GetVertexData() { List <GenericVertex> vertices = new List <GenericVertex>(); using (DataReader d = new DataReader(new MemoryStream(Mesh.VertexData.TypelessData))) { var vertexData = Mesh.VertexData; // calucate channel strides Dictionary <int, int> channelToStride = new Dictionary <int, int>(); foreach (var c in vertexData.Channels) { if (!channelToStride.ContainsKey(c.Stream)) { channelToStride.Add(c.Stream, 0); } channelToStride[c.Stream] = Math.Max(channelToStride[c.Stream], c.Offset + 4 * c.Diminsion); } for (int i = 0; i < Mesh.VertexData.VertexCount; i++) { GenericVertex v = new GenericVertex(); int index = 0; foreach (var c in vertexData.Channels) { d.Position = (uint)(i * channelToStride[c.Stream]); if (c.Stream == 1) { d.Position += (uint)(channelToStride[0] * vertexData.VertexCount); } switch (index) { case 0: if (c.Diminsion != 3 || c.Format != 0) { throw new NotSupportedException(); } v.Pos = new Vector3(d.ReadSingle(), d.ReadSingle(), d.ReadSingle()); //v.Pos = v.Pos.Xzy; break; case 1: if (c.Diminsion != 3 || c.Format != 0) { throw new NotSupportedException(); } v.Nrm = new Vector3(d.ReadSingle(), d.ReadSingle(), d.ReadSingle()); //v.Nrm = v.Nrm.Xzy; break; } index++; } vertices.Add(v); } } return(vertices); }
private static List<GenericVertex> ToGenericVertices(List<DivaVertex> inVerts) { List<GenericVertex> outVerts = new List<GenericVertex>(); foreach(var v in inVerts) { var vertex = new GenericVertex() { Pos = new Vector3(v.Position.X, v.Position.Y, v.Position.Z), Nrm = new Vector3(v.Normal.X, v.Normal.Y, v.Normal.Z), UV0 = new Vector2(v.UV0.X, v.UV0.Y), Clr = new Vector4(v.Color.X, v.Color.Y, v.Color.Z, v.Color.W) }; int weightCount = 0; if(v.Weights.X > 0) { vertex.Bones[weightCount] = v.Bones.X; vertex.Weights[weightCount++] = v.Weights.X; } if (v.Weights.Y > 0) { vertex.Bones[weightCount] = v.Bones.Y; vertex.Weights[weightCount++] = v.Weights.Y; } if (v.Weights.Z > 0) { vertex.Bones[weightCount] = v.Bones.Z; vertex.Weights[weightCount++] = v.Weights.Z; } if (v.Weights.W > 0) { vertex.Bones[weightCount] = v.Bones.W; vertex.Weights[weightCount++] = v.Weights.W; } if (v.WeightsExt.X > 0) { vertex.Bones[weightCount] = v.BonesExt.X; vertex.Weights[weightCount++] = v.WeightsExt.X; } if (v.WeightsExt.Y > 0) { vertex.Bones[weightCount] = v.BonesExt.Y; vertex.Weights[weightCount++] = v.WeightsExt.Y; } if (v.WeightsExt.Z > 0) { vertex.Bones[weightCount] = v.BonesExt.Z; vertex.Weights[weightCount++] = v.WeightsExt.Z; } if (v.WeightsExt.W > 0) { vertex.Bones[weightCount] = v.BonesExt.W; vertex.Weights[weightCount++] = v.WeightsExt.W; } outVerts.Add(vertex); } return outVerts; }
public static GenericVertex[] GetAccelDecor(RedLine line) { var linecolor = Constants.RedLineColor; var multiplier = ((RedLine)line).Multiplier; var shapecount = Math.Min(multiplier, 3); if (multiplier > 3) { shapecount += 4; } GenericVertex[] ret = new GenericVertex[3 * shapecount]; var angle = Angle.FromLine(line.End, line.Start); var angle2 = Angle.FromRadians(angle.Radians - 1.5708f); var start = line.Position2; for (int idx = 0; idx < Math.Min(multiplier, 3); idx++) { var a = start; var b = angle.MovePoint(start, line.inv ? -8 : 8); var c = angle2.MovePoint(b, 8); ret[idx * 3 + 0] = new GenericVertex((Vector2)a, linecolor); ret[idx * 3 + 1] = new GenericVertex((Vector2)b, linecolor); ret[idx * 3 + 2] = new GenericVertex((Vector2)c, linecolor); if (idx + 1 < multiplier) { start = angle.MovePoint(start, line.inv ? -2 : 2); } } if (multiplier > 3) { // Draw White plus var a = angle.MovePoint(start, line.inv ? -2 : 2); var b = angle2.MovePoint(a, 2); var c = angle2.MovePoint(b, 3); Vector2[] tall = Utility.GetThickLine( (Vector2)b, (Vector2)c, Angle.FromVector(c - b), 0.5f); Vector2[] tess = Utility.TesselateThickLine(tall); for (int i = 0; i < tess.Length; i++) { ret[3 * 3 + i] = new GenericVertex(tess[i], Color.White); } a = angle2.MovePoint(b, 1.5); b = angle.MovePoint(a, -1.5); c = angle.MovePoint(a, 1.5); tall = Utility.GetThickLine( (Vector2)b, (Vector2)c, Angle.FromVector(c - b), 0.5f); tess = Utility.TesselateThickLine(tall); for (int i = 0; i < tess.Length; i++) { ret[5 * 3 + i] = new GenericVertex(tess[i], Color.White); } } return(ret); }
public void RemoveLine(StandardLine line) { var vertexbase = _lines[line.ID]; var empty = new GenericVertex[wellsize]; _vbo.Bind(); _vbo.SetData(empty, 0, vertexbase, wellsize); _vbo.Unbind(); }
public void Open(FileItem file) { model.Skeleton = new GenericSkeleton(); using (DataReader r = new DataReader(file)) { r.BigEndian = false; r.Seek(0xCC); var somecount = r.ReadInt32(); var section1Size = r.ReadInt32(); var section2Size = r.ReadInt32(); r.ReadInt16(); var section3Size = r.ReadInt32(); r.Skip(0x0A); var section4Size = r.ReadInt32(); var section5Size = r.ReadInt32(); r.Skip(0x18); r.Skip((uint)section1Size); var mesh = new GenericMesh(); mesh.Name = "mesh1"; model.Meshes.Add(mesh); for (int i = 0; i < section2Size / 4; i++) { var v1 = r.ReadSByte(); var v2 = r.ReadSByte(); var v3 = r.ReadSByte(); var v4 = (float)r.ReadByte() / 255f; var v = new GenericVertex() { Pos = new OpenTK.Vector3(v1, v2, v3) * v4, Clr = new OpenTK.Vector4(1, 1, 1, 1) }; if (float.IsNaN(v.Pos.X) || float.IsInfinity(v.Pos.Y)) { v.Pos = new OpenTK.Vector3(); } mesh.Vertices.Add(v); Console.WriteLine(v.Pos.ToString()); } mesh.PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip; for (uint i = 0; i < mesh.Vertices.Count; i++) { mesh.Triangles.Add(i); } for (int i = 0; i < section3Size / 12; i++) { Console.WriteLine(r.ReadHalfSingle() + " " + r.ReadHalfSingle() + " " + r.ReadHalfSingle() + " " + r.ReadInt16().ToString("X") + " " + r.ReadHalfSingle() + " " + r.ReadHalfSingle()); } } }
public void Initialize(List <RedLine> lines) { Clear(); if (lines.Count == 0) { return; } //max size for init var redshapes = new GenericVertex[lines.Count * ShapeSize * 3][]; ResourceSync initsync = new ResourceSync(); int vertcount = 0; System.Threading.Tasks.Parallel.For(0, lines.Count, (idx) => { var acc = GetAccelDecor(lines[idx]); redshapes[idx] = acc; System.Threading.Interlocked.Add(ref vertcount, acc.Length); }); GenericVertex[] verts = new GenericVertex[vertcount]; _indices.EnsureCapacity(vertcount); _indices.UnsafeSetCount(vertcount); int shapepos = 0; for (int idx = 0; idx < lines.Count; idx++) { var acc = redshapes[idx]; var entry = new accelentry() { start = shapepos, shapes = acc.Length / ShapeSize }; for (int i = 0; i < acc.Length; i++) { verts[shapepos] = acc[i]; _indices.unsafe_array[shapepos] = shapepos; shapepos++; } _lookup.Add(lines[idx].ID, entry); } _vertcount = verts.Length; _accelbuffer.Bind(); EnsureVBOSize(verts.Length, false); _accelbuffer.SetData(verts, 0, 0, verts.Length); _accelbuffer.Unbind(); _accelibo.Bind(); EnsureIBOSize(_indices.Count, false); _accelibo.SetData(_indices.unsafe_array, 0, 0, _indices.Count); _accelibo.Unbind(); }
public GenericModel ToGenericModel() { var model = new GenericModel(); model.Skeleton = skeleton; var mesh = new GenericMesh(); for (int i = 0; i < PositionBuffer.Length; i++) { var vertex = new GenericVertex() { Pos = PositionBuffer[i].Xyz }; if (UV0Buffer.Length == PositionBuffer.Length) { vertex.UV0 = UV0Buffer[i]; } if (UV1Buffer.Length == PositionBuffer.Length) { vertex.UV1 = UV1Buffer[i]; } if (UV2Buffer.Length == PositionBuffer.Length) { vertex.UV2 = UV2Buffer[i]; } mesh.Vertices.Add(vertex); } List <short> tris = new List <short>(); tris.AddRange(IndexBuffer); TriangleConverter.StripToList(tris, out tris); short max = 0; foreach (var t in tris) { if (t > mesh.VertexCount) { break; } max = Math.Max(max, t); mesh.Triangles.Add((uint)t); } Console.WriteLine(max.ToString("X") + " " + mesh.VertexCount.ToString("X")); model.Meshes.Add(mesh); return(model); }
private void ReadPolygons(DataReader reader) { uint polyStartOffset = reader.Position; reader.Position += 0x14; uint uvOffset = polyStartOffset + reader.ReadUInt32(); uint triangleOffset = polyStartOffset + reader.ReadUInt32(); uint uvTriangledataSize = polyStartOffset + reader.ReadUInt32(); int polyCount = reader.ReadInt16(); reader.ReadInt16(); uint polyOffset = polyStartOffset + reader.ReadUInt32(); reader.Seek(polyOffset); for (int i = 0; i < polyCount; i++) { reader.PrintPosition(); var polyStruct = reader.ReadStruct <PolyStruct>(); var mesh = new GenericMesh(); Meshes.Add(mesh); mesh.Name = "Mesh_" + i; var temp = reader.Position; reader.Position = (uint)(triangleOffset + 3); Console.WriteLine(mesh.Name); for (int j = 0; j < polyStruct.FCount; j++) { var v = new GenericVertex(); var pos = Vertices[reader.ReadInt16()]; v.Pos = pos.Pos; v.Nrm = pos.Nrm; v.Bones = pos.Bones; v.Weights = pos.Weights; //TODO: uv and ?color? reader.ReadInt16(); // uv reader.ReadInt16(); // color mesh.Vertices.Add(v); } mesh.Optimize(); reader.Position = temp; triangleOffset += polyStruct.SectionSize; } }
private List <GenericVertex> GetCompVertexData() { List <GenericVertex> vertices = new List <GenericVertex>(); var positions = Mesh.CompVertices.GetDecompressedFloats(); for (int i = 0; i < positions.Length / 3; i++) { var vert = new GenericVertex(); vert.Pos = new Vector3(positions[i * 3 + 0], positions[i * 3 + 1], positions[i * 3 + 2]); vertices.Add(vert); } return(vertices); }
private GenericVertex SingleBind(GenericVertex vert, GenericSkeleton s) { Vector3 p = Vector3.Zero; Vector3 n = Vector3.Zero; for (int i = 0; i < 1; i++) { if (vert.Weights[i] > 0) { n += Vector3.TransformNormal(vert.Nrm, s.GetWorldTransform((int)vert.Bones[i])); // * vert.Weights[i]; p += Vector3.TransformPosition(vert.Pos, s.GetWorldTransform((int)vert.Bones[i])); // * vert.Weights[i]; } } vert.Pos = p; vert.Nrm = n; return(vert); }
public static GenericVertex[] GetWell(StandardLine line) { var angle = Angle.FromLine(line); angle.Radians += line.inv ? -1.5708 : 1.5708; //90 degrees var offset = angle.MovePoint(Vector2d.Zero, StandardLine.Zone); var wellcolor = Color.FromArgb(80, 80, 80, 80); var tl = new GenericVertex((Vector2)(line.Start), wellcolor); var tr = new GenericVertex((Vector2)(line.End), wellcolor); var bl = new GenericVertex((Vector2)(line.End + offset), wellcolor); var br = new GenericVertex((Vector2)(line.Start + offset), wellcolor); return(new GenericVertex[] { tl, tr, bl, bl, br, tl }); }
private List <GenericVertex> ToGenericVertex(GXVertex[] InVerts, List <HSD_JOBJ> BoneList, List <HSD_JOBJWeight> WeightList, HSD_JOBJ parent) { var finalList = new List <GenericVertex>(InVerts.Length); var transform = skeleton.GetWorldTransform(skeleton.Bones[jobjToIndex[parent]]); foreach (var inVert in InVerts) { GenericVertex vertex = new GenericVertex(); vertex.Pos = Vector3.TransformPosition(new Vector3(inVert.Pos.X, inVert.Pos.Y, inVert.Pos.Z), transform); vertex.Nrm = Vector3.TransformNormal(new Vector3(inVert.Nrm.X, inVert.Nrm.Y, inVert.Nrm.Z), transform); vertex.UV0 = new Vector2(inVert.TEX0.X, inVert.TEX0.Y); if (inVert.Clr0.A != 0 || inVert.Clr0.R != 0 || inVert.Clr0.G != 0 || inVert.Clr0.B != 0) { vertex.Clr = new Vector4(inVert.Clr0.R, inVert.Clr0.G, inVert.Clr0.B, inVert.Clr0.A); } vertex.Bones = new Vector4(jobjToIndex[parent], 0, 0, 0); vertex.Weights = new Vector4(1, 0, 0, 0); if (WeightList != null) { var weightList = WeightList[inVert.PMXID / 3]; // single bind fix if (weightList != null && weightList.JOBJs.Count == 1) { vertex.Pos = Vector3.TransformPosition(vertex.Pos, skeleton.GetWorldTransform(skeleton.Bones[jobjToIndex[weightList.JOBJs[0]]])); vertex.Nrm = Vector3.TransformNormal(vertex.Nrm, skeleton.GetWorldTransform(skeleton.Bones[jobjToIndex[weightList.JOBJs[0]]])); } //Bone Weights for (int i = 0; i < weightList.Weights.Count; i++) { vertex.Bones[i] = jobjToIndex[weightList.JOBJs[i]]; vertex.Weights[i] = weightList.Weights[i]; } } finalList.Add(vertex); } return(finalList); }
private GenericVertex ReadVertex(DataReader reader, int weightCount) { GenericVertex v = new GenericVertex(); v.Pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); v.Nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); if (weightCount == 1) { v.Bones = new Vector4(reader.ReadInt32(), 0, 0, 0); v.Weights = new Vector4(1, 0, 0, 0); } else if (weightCount == 2) { for (int w = 0; w < weightCount; w++) { v.Weights[w] = reader.ReadSingle(); } for (int w = 0; w < weightCount; w++) { v.Bones[w] = reader.ReadInt16(); } } else if (weightCount == 4) { for (int w = 0; w < weightCount; w++) { v.Weights[w] = reader.ReadSingle(); } for (int w = 0; w < weightCount; w++) { v.Bones[w] = reader.ReadByte(); } } return(v); }
public List <GenericVertex> GetVertex(int bufferIndex) { var buffer = Buffers[bufferIndex]; var attributes = Attributes[bufferIndex]; var max = 0; //Console.WriteLine(i + " " + buffer.Count + " " + buffer.Buffer.Length / buffer.Stride); List <GenericVertex> vertices = new List <GenericVertex>(); using (DataReader r = new DataReader(new MemoryStream(buffer.Buffer))) { for (int i = 0; i < buffer.Count; i++) { GenericVertex vert = new GenericVertex(); foreach (var att in attributes) { r.Seek((uint)(i * buffer.Stride + att.offset)); switch ((G1MVertexAttribute)att.semantic) { case G1MVertexAttribute.POSITION: //Position if (att.datatype < 4) { vert.Pos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); vert.Extra3.X = r.ReadSingle(); } else { throw new Exception("Verty 0x" + att.datatype.ToString("x")); } break; case G1MVertexAttribute.WEIGHT: //Weights? if (att.datatype == 0x0B) { vert.Weights = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle()); } else if (att.datatype == 0x02) { vert.Weights = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 0); // 4th is calculated? } else if (att.datatype == 0x03) { vert.Weights = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } else if (att.datatype == 0x0A) { vert.Weights = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), 0, 0); vert.Weights.Z = 1.0f - vert.Weights.X - vert.Weights.Y; } else { throw new Exception("Weight " + att.datatype); //Console.WriteLine(); } // break; case G1MVertexAttribute.BONES: //Nodes? if (att.datatype == 0x05) { //if(!cloth) vert.Bones = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()); //Console.WriteLine((vertBuffer[i].node/3).ToString()); } else if (att.datatype == 0x0D) { vert.Bones = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()); } else { Console.WriteLine("Bone Weight " + att.datatype); } break; case G1MVertexAttribute.NORMALS: //Normals? if (att.datatype == 0x0b) { vert.Nrm = new Vector3(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle()); vert.Extra3.Y = (r.ReadHalfSingle()); } if (att.datatype == 0x02 || att.datatype == 0x03) { vert.Nrm = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); vert.Extra3.Y = (r.ReadSingle()); } break; case G1MVertexAttribute.TEXCOORD0: //UV? var uv = Vector2.Zero; if (att.datatype == 0x0A || att.datatype == 1) { uv = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()); } else if (att.datatype == 0x5) { vert.Extra2 = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()); } else { Console.WriteLine(att.datatype); } if (att.track == 0) { vert.UV0 = uv; } break; case G1MVertexAttribute.BINORMAL: if (att.datatype == 0x02) { vert.Bit = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1); } else if (att.datatype == 0x03) { vert.Bit = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } else if (att.datatype == 0x0B) { vert.Bit = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle()); } else { throw new Exception("Unknown vertex stream 0x0A01 type."); } break; case G1MVertexAttribute.TANGENT: if (att.datatype == 0x02) { vert.Tan = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1); } else if (att.datatype == 0x03) { vert.Tan = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } else if (att.datatype == 0x0B) { vert.Tan = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle()); } else { throw new Exception("Unknown vertex stream 0x0600 type."); } break; case G1MVertexAttribute.FOG: if (att.track == 0 && att.datatype == 5) { vert.Fog = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()); } break; case G1MVertexAttribute.COLOR: var colr = Vector4.One; if (att.datatype == 0x02) { colr = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1); } else if (att.datatype == 0x03) { colr = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } else if (att.datatype == 0x0B) { colr = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle()); } else if (att.datatype == 0x0D) { colr = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f); } else { throw new Exception("Unknown vertex stream 0x0A01 type."); } if (att.track == 0) { vert.Clr = Vector4.One; // colr; } else { vert.Clr1 = colr; } break; case G1MVertexAttribute.UNK1: if (att.datatype == 0x05) { vert.Extra = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()); } break; default: //if(type.Equals("3DS")) //File.WriteAllBytes("dump.bin", buffer.Buffer); throw new Exception("Unknown Semantic " + att.semantic.ToString("x") + " " + att.offset.ToString("X")); //break; } } vertices.Add(vert); } } Console.WriteLine("Max: " + max.ToString("X")); return(vertices); }
private List <GenericVertex> ParseBuffer(byte[] buffer) { List <GenericVertex> Vertices = new List <GenericVertex>(); byte[] attributeBuffer = new byte[0]; int stride = 0; int vertexCount = 0; using (DataReader r = new DataReader(new System.IO.MemoryStream(buffer))) { r.Seek(0x4); uint attOffset = r.ReadUInt16(); int attSomething = r.ReadInt16(); uint verOffset = r.ReadUInt16(); stride = r.ReadInt16(); vertexCount = r.ReadInt32(); attributeBuffer = Decompress.Level5Decom(r.GetSection(attOffset, attSomething)); buffer = Decompress.Level5Decom(r.GetSection(verOffset, (int)(r.Length - verOffset))); } int[] ACount = new int[10]; int[] AOffet = new int[10]; int[] ASize = new int[10]; int[] AType = new int[10]; using (DataReader r = new DataReader(new System.IO.MemoryStream(attributeBuffer))) { for (int i = 0; i < 10; i++) { ACount[i] = r.ReadByte(); AOffet[i] = r.ReadByte(); ASize[i] = r.ReadByte(); AType[i] = r.ReadByte(); if (ACount[i] > 0 && i != 0 && i != 1 && i != 2 && i != 4 && i != 7 && i != 8 && i != 9) { Console.WriteLine(i + " " + ACount[i] + " " + AOffet[i] + " " + ASize[i] + " " + AType[i]); } } } using (DataReader r = new DataReader(new System.IO.MemoryStream(buffer))) { for (int i = 0; i < vertexCount; i++) { GenericVertex vert = new GenericVertex(); vert.Clr = new Vector4(1, 1, 1, 1); for (int j = 0; j < 10; j++) { r.Seek((uint)(i * stride + AOffet[j])); switch (j) { case 0: //Position vert.Pos = ReadAttribute(r, AType[j], ACount[j]).Xyz; break; case 1: //Tangent break; case 2: //Normal vert.Nrm = ReadAttribute(r, AType[j], ACount[j]).Xyz; break; case 4: //UV0 vert.UV0 = ReadAttribute(r, AType[j], ACount[j]).Xy; break; case 7: //Bone Weight vert.Weights = ReadAttribute(r, AType[j], ACount[j]); break; case 8: //Bone Index Vector4 vn = ReadAttribute(r, AType[j], ACount[j]); if (NodeTable.Length > 0 && NodeTable.Length != 1) { vert.Bones = new Vector4(NodeTable[(int)vn.X], NodeTable[(int)vn.Y], NodeTable[(int)vn.Z], NodeTable[(int)vn.W]); } break; case 9: // Color vert.Clr = ReadAttribute(r, AType[j], ACount[j]).Yzwx; break; } } Vertices.Add(vert); } } // return(Vertices); }
public void Open(FileItem File) { using (DataReader r = new DataReader(File)) { r.BigEndian = false; r.Seek(0x34); var skelTableOffset = r.Position + r.ReadUInt32(); Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); r.Seek(skelTableOffset + 8); var boneCount = r.ReadInt32(); for (int i = 0; i < boneCount; i++) { var temp = r.Position + 4; r.Seek(r.Position + r.ReadUInt32()); //r.PrintPosition(); var unk1 = r.ReadInt32(); var unk2 = r.ReadInt32(); GenericBone bone = new GenericBone(); bone.Transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var boneInfoOffset = r.Position + r.ReadUInt32(); var boneFlag = r.ReadInt32(); var parentCount = r.ReadInt32(); var childCount = r.ReadUInt32(); r.Skip(4 * childCount); // parent count intofmration r.Seek(boneInfoOffset); var parentName = r.ReadString(r.ReadInt32()); r.Skip(1); r.Align(4); bone.Name = r.ReadString(r.ReadInt32()); r.Skip(1); r.Align(4); if (parentName != "") { bone.ParentIndex = Model.Skeleton.IndexOf(Model.Skeleton.Bones.Find(e => e.Name == parentName)); } Model.Skeleton.Bones.Add(bone); r.Seek(temp); } r.Seek(0x48); var objectCount = r.ReadInt32(); var unkOffset = r.Position + r.ReadUInt32(); var vcount = 0; for (int i = 0; i < objectCount - 1; i++) { GenericMesh mesh = new GenericMesh(); Model.Meshes.Add(mesh); var temp = r.Position + 4; r.Seek(r.Position + r.ReadUInt32()); r.Skip(8); mesh.Name = r.ReadString(r.Position + r.ReadUInt32() + 4, -1); var nameOff2 = r.Position + r.ReadUInt32(); var parentBoneOff = r.Position + r.ReadUInt32(); mesh.MaterialName = r.ReadString(r.Position + r.ReadUInt32() + 12, -1); var transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var boneTableOffset = r.Position + r.ReadUInt32(); // bonetable offset r.ReadInt32(); // some matrix table? r.Skip(0x18); // floats var somecount = r.ReadInt32(); var indexTableOffset = r.Position + r.ReadUInt32(); var attributeBuffer = r.Position + r.ReadUInt32(); var vertCount = r.ReadInt32(); var primType = r.ReadInt32(); var unkownOffset2 = r.ReadUInt32(); if (unkownOffset2 > 0xFFFF) { r.ReadInt32(); } else { r.ReadInt16(); } var t = r.Position; r.Seek(attributeBuffer); var attributes = r.ReadStructArray <AttributeBuffer>(r.ReadInt32()); foreach (var a in attributes) { Console.WriteLine(a.Format + " " + a.Type + " " + a.Size); } r.Seek(t); for (int v = 0; v < vertCount; v++) { var vert = new GenericVertex(); foreach (var a in attributes) { float[] values = new float[a.Size]; for (int vi = 0; vi < values.Length; vi++) { switch (a.Format) { case 0x00: values[vi] = r.ReadSingle(); break; case 0x07: values[vi] = r.ReadInt16() / (float)short.MaxValue; break; case 0x06: values[vi] = r.ReadSByte(); break; case 0x0B: values[vi] = r.ReadUInt16() / (float)ushort.MaxValue; break; case 0x0E: values[vi] = r.ReadByte() / (float)255; break; default: throw new NotSupportedException("Unknown Attribute Format " + a.Format); } } switch (a.Type) { case 0: vert.Pos = new OpenTK.Vector3(values[0], values[1], values[2]); break; case 1: vert.Clr = new OpenTK.Vector4(values[0], values[1], values[2], values[3]); break; case 3: vert.UV0 = new OpenTK.Vector2(values[0], values[1]); break; case 15: vert.Bones = new OpenTK.Vector4(values[0], values[1], values[2], values[3]); break; case 16: vert.Weights = new OpenTK.Vector4(values[0], values[1], values[2], values[3]); break; //default: // throw new NotSupportedException("Unknown vertex attribute " + a.Type); } } mesh.Vertices.Add(vert); } r.Seek(indexTableOffset); var indexBufferSize = r.ReadInt32(); var indexCount = (indexBufferSize - 6) / 2; if (indexBufferSize > 0xFFFF) { r.ReadInt32(); } else { r.ReadInt16(); } for (int j = 0; j < indexCount; j++) { var v = r.ReadUInt16(); mesh.Triangles.Add(mesh.VertexCount < 0xFF ? (uint)(v & 0xFF) : v); } //r.PrintPosition(); Console.WriteLine(mesh.Name + " " + mesh.VertexCount.ToString("X") + " " + mesh.Triangles.Min().ToString("X") + " " + mesh.Triangles.Max().ToString("X")); //mesh.PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip; r.Seek(temp); } } }
private void ParseSubMesh(DataReader r) { GenericMesh mesh = new GenericMesh(); Model.Meshes.Add(mesh); Console.WriteLine(r.Position.ToString("X")); //0x3C size // 5 floats r.Position += 4 * 5; int index1 = r.ReadInt32(); int index2 = r.ReadInt32(); r.ReadInt32(); // 0 r.ReadInt32(); // 1 var someOffset1 = r.ReadUInt32(); // 0x38 structure var someOffset2 = r.ReadUInt32(); // 0x8 structure flag->offset to 0x60 structure r.ReadInt32(); // 0 var skinDataOffset = r.ReadUInt32(); mesh.Name = r.ReadString(r.ReadUInt32() + 4, -1); r.ReadInt32(); // 0x1C structure Console.WriteLine("\t\t" + mesh.Name + " " + someOffset1.ToString("X") + " " + someOffset2.ToString("X") + " " + skinDataOffset.ToString("X")); r.Seek(someOffset2); r.ReadInt32(); // flag or count r.Seek(r.ReadUInt32()); var vectorSize = r.ReadInt16(); var vectorCount = r.ReadInt16(); var vectorOffset = r.ReadUInt32(); Console.WriteLine(vectorOffset.ToString("x") + " " + vectorCount.ToString("X")); r.Seek(vectorOffset); for (int i = 0; i < vectorCount; i++) { var vert = new GenericVertex(); vert.Pos = new Vector3(r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue) * 100; vert.Nrm = new Vector3(r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue); mesh.Vertices.Add(vert); } r.Seek(someOffset1); r.Skip(0x1C); var dlCount = r.ReadInt16() + 1; r.Skip(0xE); var displayListPointerListOffset = r.ReadUInt32(); r.Skip(0x8); //TODO: needs attributes to read properly r.Seek(displayListPointerListOffset); for (int j = 0; j < dlCount; j++) { var off = r.ReadUInt32(); var temp = r.Position; r.Seek(off); var primType = r.ReadByte(); var primCount = r.ReadInt16(); for (int k = 0; k < primCount; k++) { //var index = r.ReadByte(); // TODO: not always bytes } r.Seek(temp); } mesh.Optimize(); }
public void Open(FileItem file) { using (DataReader r = new DataReader(file)) { r.BigEndian = true; r.Skip(0xC); // magic var faceOffset = r.ReadUInt32(); var faceLength = r.ReadInt32(); var vertexLength = r.ReadInt32(); var boneTableOffset = r.ReadUInt32(); r.ReadInt32(); // some flag usually 1 var vertOffset = r.ReadUInt32(); var faceOffset2 = r.ReadUInt32(); r.ReadInt32(); // some flag usually 1 var nameCount = r.ReadInt32(); var boneCount = r.ReadInt32(); var polyCount = r.ReadInt32(); var matLength = r.ReadInt32(); var polyNameCount2 = r.ReadInt32(); var polyNameCount3 = r.ReadInt32(); var boneTableCount = r.ReadInt32(); var boneTableCount2 = r.ReadInt32(); var stringCount = r.ReadInt32(); var UnkOffset = r.ReadInt32(); var unk = r.ReadInt32(); var boneOffset = r.ReadUInt32(); var polyInfoOffset = r.ReadUInt32(); var materialOffset = r.ReadUInt32(); var unkOffset2 = r.ReadUInt32(); var materialOffset2 = r.ReadUInt32(); var matrixOffset = r.ReadUInt32(); r.ReadInt32(); // same matrix offset var stringOffset = r.ReadInt32(); r.Seek(boneOffset); for (int i = 0; i < boneCount; i++) { GenericBone bone = new GenericBone(); bone.Name = r.ReadString(r.ReadUInt32(), -1); r.ReadInt32(); // hash var parentName = r.ReadString(r.ReadUInt32(), -1); r.ReadInt32(); // hash r.Skip(0x14); // various unimportant stuff var pos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var sca = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.Skip(0x14); // various unimportant stuff var inverseMatrix = new Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var matrix = new Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.Skip(0xC); // various unimportant stuff bone.Transform = inverseMatrix.Inverted(); bone.Position = pos; bone.ParentIndex = Skeleton.Bones.FindIndex(e => e.Name == parentName); Skeleton.Bones.Add(bone); } r.Seek(materialOffset); for (int i = 0; i < matLength / 6; i++) { GenericMaterial mat = new GenericMaterial(); r.PrintPosition(); var name = r.ReadString(r.ReadUInt32(), -1); if (name == "") { name = "null"; } r.Skip(0x110); mat.TextureDiffuse = r.ReadString(r.ReadUInt32(), -1); r.Skip(0x110); if (Generic.MaterialBank.ContainsKey(name)) { name += "_" + i; } if (!Generic.TextureBank.ContainsKey(mat.TextureDiffuse)) { Generic.TextureBank.Add(mat.TextureDiffuse, new GenericTexture() { Name = mat.TextureDiffuse }); } Generic.MaterialBank.Add(name, mat); } r.Seek(faceOffset); var Indices = new ushort[faceLength / 2]; for (int i = 0; i < Indices.Length; i++) { Indices[i] = r.ReadUInt16(); } r.Seek(vertOffset); var Vertices = new GenericVertex[vertexLength / 44]; for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = new GenericVertex() { Pos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()), Nrm = new Vector3(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f), Extra = new Vector4(r.ReadByte()), Clr = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f), UV0 = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()), UV1 = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()), Bones = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()), Weights = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f), Extra2 = new Vector4(r.ReadSingle(), r.ReadSingle(), 0, 0) }; } var indexOffset = 0; var vertexOffset = 0; r.Seek(polyInfoOffset); for (int i = 0; i < polyCount; i++) { GenericMesh mesh = new GenericMesh(); mesh.Name = r.ReadString(r.ReadUInt32(), -1); r.ReadInt32();//hash var myboneTableOffset = r.ReadUInt32(); var myPolyOffset = r.ReadInt32(); r.Skip(8); var indexCount = r.ReadInt32(); var vertCount = r.ReadInt32(); var boneIDCount = r.ReadInt32(); var materialID = r.ReadInt32(); r.Skip(8); mesh.MaterialName = Generic.MaterialBank.Keys.ToList()[materialID]; // read bone table var temp = r.Position; var boneTable = new int[boneIDCount]; r.Seek(myboneTableOffset); for (int j = 0; j < boneIDCount; j++) { boneTable[j] = r.ReadInt32(); } // get indices for (int j = 0; j < indexCount; j++) { mesh.Triangles.Add(Indices[indexOffset + j]); } indexOffset += indexCount; // get vertices for (int j = 0; j < vertCount; j++) { var vert = Vertices[vertexOffset + j]; if (boneIDCount == 1) { vert.Weights = new Vector4(1, 0, 0, 0); vert.Bones = new Vector4(0, 0, 0, 0); } if (boneIDCount != 0) { for (int k = 0; k < 4; k++) { if (vert.Weights[k] > 0) { vert.Bones[k] = boneTable[(int)vert.Bones[k]]; } } } if (vert.Weights[0] == 1 && boneIDCount == 1) { vert.Pos = Vector3.TransformPosition(vert.Pos, Skeleton.GetWorldTransform(Skeleton.Bones[(int)vert.Bones[0]])); vert.Nrm = Vector3.TransformNormal(vert.Nrm, Skeleton.GetWorldTransform(Skeleton.Bones[(int)vert.Bones[0]])); } vert.Nrm.Normalize(); mesh.Vertices.Add(vert); } vertexOffset += vertCount; r.Seek(temp); //Console.WriteLine(mesh.Name + " " + (myPolyOffset / 2).ToString("X") + " " + myboneTableOffset.ToString("X")); Generic.Meshes.Add(mesh); } } }
public void Open(FileItem File) { var skelPath = File.FilePath.Replace(".mdg", ".anm"); var skelAngPath = File.FilePath.Replace(".mdg", ".ang"); var modelPath = File.FilePath.Replace(".mdg", ".mdl"); var texPath = File.FilePath.Replace(".mdg", ".tex"); if (!System.IO.File.Exists(skelPath)) { System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelPath)); return; } if (!System.IO.File.Exists(skelAngPath)) { System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelAngPath)); return; } if (!System.IO.File.Exists(modelPath)) { System.Windows.Forms.MessageBox.Show("Missing Model File " + Path.GetFileName(modelPath)); return; } Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); if (System.IO.File.Exists(texPath)) { using (DataReader r = new DataReader(new FileStream(texPath, FileMode.Open))) { r.BigEndian = true; var unk = r.ReadInt32(); var width = r.ReadInt32(); var height = r.ReadInt32(); var dataLength = r.ReadInt32(); var padding = r.ReadInt32(); var format = r.ReadByte(); var data = r.GetSection(0x20, (int)(r.BaseStream.Length - 0x20)); var bmp = HSDLib.Helpers.TPL.ConvertFromTextureMelee(data, width, height, (int)TPL_TextureFormat.CMP, null, 0, 0); GenericTexture t = new GenericTexture(); t.FromBitmap(bmp); bmp.Dispose(); Model.TextureBank.Add("texture", t); Model.MaterialBank.Add("material", new GenericMaterial() { TextureDiffuse = "texture" }); } } using (DataReader r = new DataReader(new FileStream(skelPath, FileMode.Open))) { r.BigEndian = false; r.ReadInt32(); // magic r.ReadInt32(); // header var boneCount = r.ReadInt32(); var boneOffset = r.ReadUInt32(); using (DataReader angr = new DataReader(new FileStream(skelAngPath, FileMode.Open))) { angr.BigEndian = false; for (int i = 0; i < boneCount; i++) { r.Seek(boneOffset + (uint)(i * 0x20)); var bone = new GenericBone(); bone.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); //r.Skip(0x10); // inverted world position bone.Name = r.ReadString(r.ReadUInt32(), -1); bone.ParentIndex = r.ReadInt32(); var flags = r.ReadInt32(); var angOffset = r.ReadUInt32(); /*angr.Seek(angOffset); * angr.Skip(4); * var posOff = angr.ReadUInt32(); * var rotOff = angr.ReadUInt32(); * var scaOff = angr.ReadUInt32(); * angr.Seek(posOff); * bone.Position = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle()); * angr.Seek(rotOff); * bone.Rotation = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle()); * angr.Seek(scaOff); * bone.Scale = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());*/ Model.Skeleton.Bones.Add(bone); } } } Model.Skeleton.TransformWorldToRelative(); using (DataReader r = new DataReader(new FileStream(modelPath, FileMode.Open))) { r.BigEndian = true; r.ReadInt32(); // magic int boneCount = r.ReadInt16(); var meshCount = r.ReadInt16(); boneCount = r.ReadInt32(); var meshOffset = r.ReadUInt32(); r.ReadUInt32(); var boneOffset = r.ReadUInt32(); for (int i = 0; i < meshCount; i++) { r.Seek(meshOffset + (uint)(i * 80)); r.Skip(0x30); // bounding stuff var mesh = new GenericMesh(); mesh.MaterialName = "material"; mesh.Name = r.ReadString(r.ReadUInt32(), -1); r.Skip(4 * 4); var datInfoOffset = r.ReadUInt32(); Model.Meshes.Add(mesh); r.Seek(datInfoOffset); var flag = r.ReadInt32(); var bufferOffset = r.ReadUInt32(); var someCount = r.ReadInt32(); var primCount = r.ReadInt32(); using (DataReader buffer = new DataReader(new FileStream(File.FilePath, FileMode.Open))) { buffer.BigEndian = true; if (new string(buffer.ReadChars(4)) == "MDG5") { buffer.Seek(0x10); } else { buffer.Seek(0); } buffer.Skip(bufferOffset); for (int p = 0; p < primCount; p++) { var primitiveType = buffer.ReadInt16(); var pcount = buffer.ReadInt16(); if (primitiveType != 0x98) { throw new NotSupportedException("Unknown prim type " + primitiveType.ToString("X")); } var strip = new List <GenericVertex>(); for (int v = 0; v < pcount; v++) { var vert = new GenericVertex(); vert.Pos = new OpenTK.Vector3(buffer.ReadSingle(), buffer.ReadSingle(), buffer.ReadSingle()); vert.Nrm = new OpenTK.Vector3(buffer.ReadSByte(), buffer.ReadSByte(), buffer.ReadSByte()); vert.Nrm.Normalize(); // Color? int col = buffer.ReadInt16(); var R = (col >> 12) & 0xF; var G = (col >> 8) & 0xF; var B = (col >> 4) & 0xF; var A = (col) & 0xF; vert.Clr = new OpenTK.Vector4( (R | R << 4) / (float)0xFF, (G | G << 4) / (float)0xFF, (B | B << 4) / (float)0xFF, (A | A << 4) / (float)0xFF); vert.UV0 = new OpenTK.Vector2(buffer.ReadInt16() / (float)0xFFF, buffer.ReadInt16() / (float)0xFFF); var weight1 = buffer.ReadByte() / (float)0xFF; float weight2 = 0; if (weight1 != 1) { weight2 = 1 - weight1; } var bone1 = buffer.ReadByte(); var bone2 = buffer.ReadByte(); vert.Bones = new OpenTK.Vector4(bone1, bone2, 0, 0); vert.Weights = new OpenTK.Vector4(weight1, weight2, 0, 0); strip.Add(vert); } TriangleConverter.StripToList(strip, out strip); mesh.Vertices.AddRange(strip); } } mesh.Optimize(); } } }
public void ParseOBE(byte[] data) { DataReader reader = new DataReader(new MemoryStream(data)); reader.BigEndian = true; reader.Position = 0x20; var vertexCount = reader.ReadUInt32(); var vertexOffset = reader.ReadUInt32(); var dataChunkCount = reader.ReadInt32(); var dataChunkOffset = reader.ReadUInt32(); var dataOffset = reader.ReadUInt32(); int[] chunkCounts = new int[dataChunkCount]; reader.Position = dataChunkOffset; for (int i = 0; i < dataChunkCount; i++) { chunkCounts[i] = reader.ReadInt32(); reader.Position += 12; // there's a hash here too } int totalChunks = 0; reader.Position = dataOffset; foreach (var count in chunkCounts) { var vertices = new List <MeshObject>(); meshGroups.Add(vertices); totalChunks += count; for (int i = 0; i < count; i++) { // GAMECUBE var ob = new MeshObject(); ob.PrimitiveType = reader.ReadInt16() >> 8; ob.VertexCount = reader.ReadInt16(); ob.BoneIndices = new int[reader.ReadByte()]; ob.UnkCount = reader.ReadByte(); reader.Position += 2; for (int bi = 0; bi < ob.BoneIndices.Length; bi++) { ob.BoneIndices[bi] = reader.ReadByte(); } vertices.Add(ob); reader.Position += (uint)(0xA - ob.BoneIndices.Length); // XBOX /*var ob = new MeshObject() * { * PrimitiveType = reader.ReadInt16(), * VertexCount = reader.ReadInt16(), * }; * ob.BoneIndices = new int[reader.ReadInt16()]; * ob.UnkCount = reader.ReadInt16(); * * Console.WriteLine(ob.VertexCount.ToString("X") + " " + ob.PrimitiveType); * * for (int bi = 0; bi < ob.BoneIndices.Length; bi++) * ob.BoneIndices[bi] = reader.ReadByte(); * * meshObjects.Add(ob); * * reader.Position += (uint)(0x30 - ob.BoneIndices.Length);*/ } } reader.Position = 0xA0; // 0x80 var ModelInfoOffset = reader.ReadUInt32(); var ModelInfoCount = reader.ReadUInt32(); ParseBone(reader, ModelInfoOffset); //Skeleton.TransformWorldToRelative(); reader.Position = 0x94; var SomeOffset = reader.ReadUInt32(); var SomeCount = reader.ReadUInt32(); for (var ob = 0; ob < SomeCount; ob++) { var hash = reader.ReadUInt32(); var c = reader.ReadUInt16(); } reader.Position = 0x50; int maxBoneWeight = reader.ReadByte(); reader.ReadByte(); int flag = reader.ReadUInt16(); var VertexTableReaderOffset = reader.ReadUInt32(); var VertexTableOffset = reader.ReadUInt32(); var VertexTableSize = reader.ReadUInt32(); var positionTableOffset = reader.ReadUInt32(); var normalTableOffset = reader.ReadUInt32(); var uvTableOffset = reader.ReadUInt32(); var colorTableOffset = reader.ReadUInt32(); reader.ReadUInt32(); //vertex count reader.ReadUInt32(); //normal count var morphTargetOffset = reader.ReadUInt32(); if (flag == 0x12 || flag == 0x1A) { reader.Position = VertexTableReaderOffset; for (int i = 0; i < totalChunks; i++) { var offset = reader.ReadUInt32(); var size = reader.ReadUInt32(); var temp = reader.Position; reader.Position = VertexTableOffset + offset; int primType = reader.ReadInt16(); int vertCount = reader.ReadInt16(); for (int v = 0; v < vertCount; v++) { if (maxBoneWeight == 1) { reader.ReadByte(); // bone probably divide by 3 } var vertexIndex = reader.ReadInt16(); var normalIndex = reader.ReadInt16(); var colorIndex = reader.ReadInt16(); var uvIndex = reader.ReadInt16(); var temp2 = reader.Position; var vertex = new GenericVertex(); int stride = 0x20; if (maxBoneWeight == 1) { stride = 0x10; } reader.Position = (uint)(vertexOffset + stride * vertexIndex); vertex.Pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); if (maxBoneWeight == 1) { vertex.Bones = new Vector4(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); vertex.Weights = new Vector4(1, 0, 0, 0); //Console.WriteLine(vertex.Bones.ToString());//TODO: I don't understand } else if (maxBoneWeight == 2 || maxBoneWeight == 3 || maxBoneWeight == 4) { vertex.Bones = new Vector4(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); vertex.Weights = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0); reader.ReadSingle(); } else { throw new NotImplementedException($"Bone Weight {maxBoneWeight} not supported"); } //reader.Position = (uint)(positionTableOffset + 12 * vertexIndex); //vertex.Pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.Position = (uint)(normalTableOffset + 3 * normalIndex); vertex.Nrm = new Vector3(reader.ReadSByte(), reader.ReadSByte(), reader.ReadSByte()); vertex.Nrm.Normalize(); reader.Position = (uint)(uvTableOffset + 8 * uvIndex); vertex.UV0 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); reader.Position = (uint)(colorTableOffset + 4 * colorIndex); vertex.Clr = new Vector4(reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f); vertices.Add(vertex); reader.Position = temp2; } reader.Position = temp; } //FixBoneIndices(); } else { reader.Position = vertexOffset; for (var v = 0; v < vertexCount; v++) { // GAMECUBE var vertex = new GenericVertex(); vertex.Pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); vertex.Weights = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0); vertex.Bones = new Vector4(reader.ReadByte() / 3, reader.ReadByte() / 3, reader.ReadByte() / 3, reader.ReadByte() / 3); vertex.Nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); vertex.Clr = new Vector4(reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f); vertex.UV0 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); vertices.Add(vertex); } FixBoneIndices(); } //Morphs ------------------------ reader.Position = morphTargetOffset; var numOfMorphs = reader.ReadInt32(); var morphVertexCount = reader.ReadInt32(); var morphFlag = reader.ReadInt32(); reader.Position = morphTargetOffset + 0x40; for (int m = 0; m < numOfMorphs; m++) { var MorphVertex = new Dictionary <int, GenericVertex>(); for (int i = 0; i < morphVertexCount; i++) { var morphPos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int vertexPosition = reader.ReadInt32(); var morphNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.ReadInt32(); // ?? if (morphFlag == 1) { reader.Position += 16; } MorphVertex.Add(vertexPosition, new GenericVertex() { Pos = vertices[vertexPosition].Pos + morphPos, Nrm = morphNormal }); /*if(m == 7) * { * var vertex = vertices[vertexPosition]; * vertex.Pos = vertices[vertexPosition].Pos + morphPos; * vertices[vertexPosition] = vertex; * }*/ } _morphs.Add($"Morph_{m}", MorphVertex); } }
public GenericModel ToGenericModel() { var mdl = new GenericModel() { Skeleton = Skeleton };; byte[] Data = File.ReadAllBytes(@"chr0020_model.npki"); byte[] ImageData = File.ReadAllBytes(@"chr0020_model.npkv"); foreach (var t in TXRs) { GenericTexture tex = new GenericTexture(); tex.Width = (uint)t.Width; tex.Height = (uint)t.Height; var buf = new byte[t.Width * t.Height / 2]; Array.Copy(ImageData, t.BufferOffsets[0], buf, 0, buf.Length); buf = VitaSwizzle.UnswizzlePS4(buf, t.Width, t.Height); tex.Mipmaps.Add(buf); tex.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.CompressedRgbS3tcDxt1Ext; if (!mdl.TextureBank.ContainsKey(t.Name)) { mdl.TextureBank.Add(t.Name, tex); } Console.WriteLine(tex.Width + " " + tex.Height + " " + t.Unknown.ToString("X") + " " + t.BufferOffsets[0].ToString("X") + " " + t.BufferSizes[0].ToString("X")); } foreach (var v in VTXs) { if (v.BufferSizes.Length < 2) { continue; } GenericMesh m = new GenericMesh(); mdl.Meshes.Add(m); m.Name = v.Name; using (DataReader r = new DataReader(Data)) { for (uint i = 0; i < v.BufferSizes[1]; i += 2) { r.Seek((uint)v.BufferOffsets[1] + i); //r.PrintPosition(); var index = r.ReadInt16(); GenericVertex vert = new GenericVertex(); foreach (var attr in v.Attribtues) { r.Seek((uint)(v.BufferOffsets[0] + v.BufferInfos[attr.RESBufferIndex].Offset + index * v.BufferInfos[attr.RESBufferIndex].Stride + attr.BufferOffset)); switch (attr.AttributeName) { case 1: vert.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); break; case 2: vert.Nrm = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); break; case 5: vert.UV0 = new OpenTK.Vector2(r.ReadSingle(), r.ReadSingle()); break; case 8: var b1 = v.Bones[r.ReadInt32()]; var b2 = v.Bones[r.ReadInt32()]; var b3 = v.Bones[r.ReadInt32()]; var b4 = v.Bones[r.ReadInt32()]; vert.Bones = new OpenTK.Vector4(Skeleton.IndexOf(Skeleton.GetBoneByName(b1)), Skeleton.IndexOf(Skeleton.GetBoneByName(b2)), Skeleton.IndexOf(Skeleton.GetBoneByName(b3)), Skeleton.IndexOf(Skeleton.GetBoneByName(b4))); break; case 7: vert.Weights = new OpenTK.Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); break; } } if (v.Bones.Count == 1) { vert.Bones = new OpenTK.Vector4(Skeleton.IndexOf(Skeleton.GetBoneByName(v.Bones[0])), 0, 0, 0); vert.Weights = new OpenTK.Vector4(1, 0, 0, 0); } m.Vertices.Add(vert); m.Triangles.Add(i / 2); //Console.WriteLine(index + " " + v.BufferOffsets[0].ToString("X") + " " + v.BufferInfos[0].Offset + " " + v.BufferInfos[0].Stride); } //m.Optimize(); } } return(mdl); }
public void Export(string FilePath, GenericModel Model) { using (StreamWriter w = new StreamWriter(new FileStream(FilePath, FileMode.Create))) { w.WriteLine("version 1"); if (Model.Skeleton != null) { w.WriteLine("nodes"); foreach (GenericBone bone in Model.Skeleton.Bones) { w.WriteLine($" {Model.Skeleton.IndexOf(bone)} \"{bone.Name}\" {bone.ParentIndex}"); } // meshNodes foreach (var mesh in Model.Meshes) { w.WriteLine($" {Model.Skeleton.Bones.Count + Model.Meshes.IndexOf(mesh)} \"{mesh.Name}\" -1"); } w.WriteLine("end"); w.WriteLine("skeleton"); w.WriteLine("time 0"); foreach (GenericBone bone in Model.Skeleton.Bones) { w.WriteLine($" {Model.Skeleton.IndexOf(bone)} {bone.Position.X} {bone.Position.Y} {bone.Position.Z} {bone.Rotation.X} {bone.Rotation.Y} {bone.Rotation.Z}"); } foreach (var mesh in Model.Meshes) { w.WriteLine($" {Model.Skeleton.Bones.Count + Model.Meshes.IndexOf(mesh)} 0 0 0 0 0 0"); } w.WriteLine("end"); } w.WriteLine("triangles"); Dictionary <GenericTexture, string> TextureBank = new Dictionary <GenericTexture, string>(); foreach (GenericMesh m in Model.Meshes) { if (!m.Export) { continue; } var meshIndex = Model.Skeleton.Bones.Count + Model.Meshes.IndexOf(m); m.MakeTriangles(); string MaterialName = m.Name; if (m.MaterialName != null && Model.MaterialBank.ContainsKey(m.MaterialName)) { var material = Model.MaterialBank[m.MaterialName]; if (material.TextureDiffuse != null && Model.TextureBank.ContainsKey(material.TextureDiffuse)) { var texture = Model.TextureBank[material.TextureDiffuse]; if (TextureBank.ContainsKey(texture)) { MaterialName = TextureBank[texture]; } else { string TextureName = material.TextureDiffuse.Equals("") ? "Texture_" + TextureBank.Count + ".png" : material.TextureDiffuse + ".png"; if (texture.Mipmaps.Count != 0) { Rendering.RenderTexture Temp = new Rendering.RenderTexture(); Temp.LoadGenericTexture(texture); Temp.ExportPNG(new FileInfo(FilePath).Directory.FullName + "/" + TextureName); Temp.Delete(); } TextureBank.Add(texture, TextureName); MaterialName = TextureName; } } } for (int i = 0; i < m.Triangles.Count; i += 3) { w.WriteLine(MaterialName); { GenericVertex v = m.Vertices[(int)m.Triangles[i]]; w.WriteLine($" {meshIndex} {v.Pos.X} {v.Pos.Y} {v.Pos.Z} {v.Nrm.X} {v.Nrm.Y} {v.Nrm.Z} {v.UV0.X} {v.UV0.Y} " + WriteWeights(v)); } { GenericVertex v = m.Vertices[(int)m.Triangles[i + 1]]; w.WriteLine($" {meshIndex} {v.Pos.X} {v.Pos.Y} {v.Pos.Z} {v.Nrm.X} {v.Nrm.Y} {v.Nrm.Z} {v.UV0.X} {v.UV0.Y} " + WriteWeights(v)); } { GenericVertex v = m.Vertices[(int)m.Triangles[i + 2]]; w.WriteLine($" {meshIndex} {v.Pos.X} {v.Pos.Y} {v.Pos.Z} {v.Nrm.X} {v.Nrm.Y} {v.Nrm.Z} {v.UV0.X} {v.UV0.Y} " + WriteWeights(v)); } } } w.WriteLine("end"); w.Close(); } if (Model.HasMorphs) { WriteVTA(FilePath.Replace(".smd", ".vta"), Model); } }
public void Open(FileItem File) { dynamic stuff = JObject.Parse(System.Text.Encoding.UTF8.GetString(File.GetFileBinary())); Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); var skeletons = stuff.skeletons; foreach (var skel in skeletons) { if (((string)skel.name).Contains("carryable")) { foreach (var bone in skel.bones) { var gBone = new GenericBone(); Model.Skeleton.Bones.Add(gBone); gBone.Name = "Bone_" + bone.index; gBone.ParentIndex = bone.parent; gBone.Position = new OpenTK.Vector3((float)bone.local.position[0], (float)bone.local.position[1], (float)bone.local.position[2]); gBone.QuaternionRotation = new OpenTK.Quaternion((float)bone.local.rotation[0], (float)bone.local.rotation[1], (float)bone.local.rotation[2], (float)bone.local.rotation[3]).Inverted(); gBone.Scale = new OpenTK.Vector3((float)bone.local.scale[0], (float)bone.local.scale[1], (float)bone.local.scale[2]); } break; } } var models = stuff.models; foreach (var modl in models) { foreach (var batch in modl.batches) { GenericMesh mesh = new GenericMesh(); Model.Meshes.Add(mesh); mesh.Name = batch.id; foreach (int index in batch.indices) { var vertex = new GenericVertex(); if (((JArray)batch.positions).Count > 0) { vertex.Pos = new OpenTK.Vector3((float)batch.positions[index * 3 + 0], (float)batch.positions[index * 3 + 1], (float)batch.positions[index * 3 + 2]); } if (((JArray)batch.normals).Count > 0) { vertex.Nrm = new OpenTK.Vector3((float)batch.normals[index * 3 + 0], (float)batch.normals[index * 3 + 1], (float)batch.normals[index * 3 + 2]); } if (((JArray)batch.uvs).Count > 0) { vertex.UV0 = new OpenTK.Vector2((float)batch.uvs[index * 2 + 0], (float)batch.uvs[index * 2 + 1]); } if (((JArray)batch.uvs2).Count > 0) { vertex.UV1 = new OpenTK.Vector2((float)batch.uvs2[index * 2 + 0], (float)batch.uvs2[index * 2 + 1]); } if (((JArray)batch.uvs3).Count > 0) { vertex.UV2 = new OpenTK.Vector2((float)batch.uvs3[index * 2 + 0], (float)batch.uvs3[index * 2 + 1]); } if (((JArray)batch.colors).Count > 0) { vertex.Clr = new OpenTK.Vector4((float)batch.colors[index * 4 + 0] * 255, (float)batch.colors[index * 4 + 1] * 255, (float)batch.colors[index * 4 + 2] * 255, (float)batch.colors[index * 4 + 3] * 255); } if (((JArray)batch.bindings).Count > 0) { vertex.Bones = new OpenTK.Vector4((int)batch.bindings[index * 4 + 0], (int)batch.bindings[index * 4 + 1], (int)batch.bindings[index * 4 + 2], (int)batch.bindings[index * 4 + 3]); } if (((JArray)batch.weights).Count > 0) { vertex.Weights = new OpenTK.Vector4(((int)batch.weights[index * 4 + 0]) / 255f, ((int)batch.weights[index * 4 + 1]) / 255f, ((int)batch.weights[index * 4 + 2]) / 255f, ((int)batch.weights[index * 4 + 3]) / 255f); } mesh.Vertices.Add(vertex); } mesh.Optimize(); } } }
private void ParseMDLD(byte[] data) { using (DataReader r = new DataReader(data)) { r.BigEndian = false; r.ReadInt32(); // magic var offset1 = r.ReadUInt32(); var polyInfoOffset = r.ReadUInt32(); var polyInfoCount = r.ReadInt32(); var boneOffset = r.ReadUInt32(); var boneCount = r.ReadInt32(); var bufferOffset = r.ReadUInt32(); var bufferLength = r.ReadInt32(); var vertexCount = r.ReadInt32(); var att = r.ReadString(0x68, -1).Split('_'); r.Seek(boneOffset); model.Skeleton = new GenericSkeleton(); for (int i = 0; i < boneCount; i++) { var bone = new GenericBone(); bone.Name = r.ReadString(r.Position, -1); r.Skip(0x20); bone.Transform = Matrix4.Identity; bone.QuaternionRotation = new Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); bone.Position = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); bone.Scale = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); bone.ParentIndex = r.ReadInt32(); model.Skeleton.Bones.Add(bone); } model.Skeleton.TransformWorldToRelative(); List <GenericVertex> vertices = new List <GenericVertex>(); for (uint i = 0; i < vertexCount; i++) { r.Seek(bufferOffset + 60 * i); var vert = new GenericVertex(); var stop = false; foreach (var va in att) { switch (va) { case "vp3": vert.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); break; case "vc": vert.Clr = new OpenTK.Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f); break; case "vn": vert.Nrm = new OpenTK.Vector3(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle()); r.ReadHalfSingle(); break; case "vt": vert.UV0 = new OpenTK.Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()); break; case "von": r.Skip(8); break; case "vb4": vert.Bones = new OpenTK.Vector4(r.ReadInt16(), r.ReadInt16(), r.ReadInt16(), r.ReadInt16()); vert.Weights = new OpenTK.Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); break; case "vs": break; default: stop = true; break; } if (stop) { break; } } vertices.Add(vert); } r.Seek(polyInfoOffset); for (int i = 0; i < polyInfoCount; i++) { GenericMesh mesh = new GenericMesh(); model.Meshes.Add(mesh); mesh.Name = r.ReadString(r.Position, -1); r.Skip(0x40); var polyBufferOffset = r.ReadUInt32(); var polyBufferLength = r.ReadUInt32(); var polyBufferCount = r.ReadUInt32(); var primType = r.ReadInt32(); r.Skip(0x60); var temp = r.Position; r.Seek(polyBufferOffset); for (int j = 0; j < polyBufferCount; j++) { if (primType == 4) { mesh.Vertices.Add(vertices[r.ReadInt32()]); } } mesh.Optimize(); r.Seek(temp); } } }