/// <summary> /// Gets the index of a value in the buffer /// </summary> /// <param name="v"></param> /// <param name="o"></param> /// <returns></returns> private ushort GetIndex(GXAttribName attributeName, float[] o) { if (!nameToAttr.ContainsKey(attributeName)) { GX_Attribute a = new GX_Attribute(); a.AttributeName = attributeName; nameToIndexHash.Add(attributeName, new Dictionary <int, int>()); nameToAttr.Add(attributeName, a); attrToNewData.Add(a, new List <float[]>()); } var hashToIndex = nameToIndexHash[attributeName]; var index = 0; var hash = string.Join("", o).GetHashCode();// ((IStructuralEquatable)o).GetHashCode(EqualityComparer<float>.Default); if (hashToIndex.ContainsKey(hash)) { index = hashToIndex[hash]; } else { var vals = attrToNewData[nameToAttr[attributeName]]; index = vals.Count; vals.Add(o); hashToIndex.Add(hash, index); } return((ushort)index); }
public override void Open(HSDReader Reader) { Name = (GXAttribName)Reader.ReadUInt32(); AttributeType = (GXAttribType)Reader.ReadUInt32(); CompCount = (GXCompCnt)Reader.ReadInt32(); CompType = (GXCompType)Reader.ReadUInt32(); Scale = Reader.ReadByte(); Reader.ReadByte();//Padding Stride = Reader.ReadUInt16(); Offset = Reader.ReadUInt32(); }
/// <summary> /// /// </summary> /// <param name="objFileStream"></param> /// <returns></returns> public static HSD_JOBJ GenerateEmblemModel(EmblemModel model) { List <GX_Vertex> vertexList = new List <GX_Vertex>(); foreach (var ve in model.f) { foreach (var i in ve) { var x = ((model.v[i - 1][0] - model.xRange.X) / Math.Abs(model.xRange.Y - model.xRange.X)) * model.aspectX; var y = (1 - (model.v[i - 1][2] - model.yRange.X) / Math.Abs(model.xRange.Y - model.yRange.X)) * model.aspectY; vertexList.Add(new GX_Vertex() { POS = new GXVector3(x * 6 - 3, y * 6 - 3, 0) }); } } HSD_JOBJ jobj = new HSD_JOBJ(); jobj.Flags = JOBJ_FLAG.CLASSICAL_SCALING | JOBJ_FLAG.XLU; jobj.SX = 3; jobj.SY = 3; jobj.SZ = 3; jobj.TZ = 67.4f; HSD_DOBJ dobj = new HSD_DOBJ(); dobj.Mobj = new HSD_MOBJ() { RenderFlags = RENDER_MODE.CONSTANT | RENDER_MODE.NO_ZUPDATE | RENDER_MODE.XLU, Material = new HSD_Material() { Alpha = 0.6f, Shininess = 50, DiffuseColor = Color.FromArgb(255, 128, 128, 230), SpecularColor = Color.FromArgb(255, 255, 255, 255), AmbientColor = Color.FromArgb(255, 128, 128, 128), } }; jobj.Dobj = dobj; POBJ_Generator pobjGen = new POBJ_Generator(); GXAttribName[] attrs = new GXAttribName[] { GXAttribName.GX_VA_POS, GXAttribName.GX_VA_NULL }; dobj.Pobj = pobjGen.CreatePOBJsFromTriangleList(vertexList, attrs, null); dobj.Pobj.Flags = 0; pobjGen.SaveChanges(); return(jobj); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="type"></param> /// <returns></returns> private static int CompTypeToInt(GXAttribName name, GXCompType type) { switch (name) { case GXAttribName.GX_VA_CLR0: case GXAttribName.GX_VA_CLR1: switch (type) { case GXCompType.RGBA4: case GXCompType.RGB565: return(2); case GXCompType.RGB8: case GXCompType.RGBA6: return(3); case GXCompType.RGBX8: case GXCompType.RGBA8: return(4); default: return(0); } default: switch (type) { case GXCompType.Int8: case GXCompType.UInt8: return(1); case GXCompType.Int16: case GXCompType.UInt16: return(2); case GXCompType.Float: return(4); default: return(0); } } }
public static HSD_DOBJ GenerateOutlineMesh(HSD_DOBJ DOBJ) { var settings = new OutlineSettings(); using (PropertyDialog d = new PropertyDialog("Outline Settings", settings)) { if (d.ShowDialog() != DialogResult.OK) { return(null); } } var pobjGen = new POBJ_Generator(); pobjGen.UseTriangleStrips = settings.UseStrips; var newDOBJ = new HSD_DOBJ(); newDOBJ.Mobj = new HSD_MOBJ() { Material = new HSD_Material() { AmbientColor = Color.White, SpecularColor = Color.Black, DiffuseColor = settings.Color, DIF_A = 255, SPC_A = 255, AMB_A = 255, Shininess = 50, Alpha = 1 }, RenderFlags = RENDER_MODE.CONSTANT }; foreach (var pobj in DOBJ.Pobj.List) { var dl = pobj.ToDisplayList(); var vertices = dl.Vertices; GXAttribName[] attrs = new GXAttribName[] { GXAttribName.GX_VA_POS, GXAttribName.GX_VA_NULL }; if (pobj.HasAttribute(GXAttribName.GX_VA_PNMTXIDX)) { attrs = new GXAttribName[] { GXAttribName.GX_VA_PNMTXIDX, GXAttribName.GX_VA_POS, GXAttribName.GX_VA_NULL }; } List <GX_Vertex> newVerties = new List <GX_Vertex>(); var offset = 0; foreach (var prim in dl.Primitives) { var verts = vertices.GetRange(offset, prim.Count); offset += prim.Count; switch (prim.PrimitiveType) { case GXPrimitiveType.Quads: verts = TriangleConverter.QuadToList(verts); break; case GXPrimitiveType.TriangleStrip: verts = TriangleConverter.StripToList(verts); break; case GXPrimitiveType.Triangles: break; default: Console.WriteLine(prim.PrimitiveType); break; } newVerties.AddRange(verts); } // extrude for (int i = 0; i < newVerties.Count; i++) { var v = newVerties[i]; v.POS.X += v.NRM.X * settings.Size; v.POS.Y += v.NRM.Y * settings.Size; v.POS.Z += v.NRM.Z * settings.Size; //v.CLR0.R = settings.Color.R / 255f; //v.CLR0.G = settings.Color.G / 255f; //v.CLR0.B = settings.Color.B / 255f; //v.CLR0.A = settings.Color.A / 255f; newVerties[i] = v; } // invert faces for (int i = 0; i < newVerties.Count; i += 3) { var temp = newVerties[i]; newVerties[i] = newVerties[i + 2]; newVerties[i + 2] = temp; } var newpobj = pobjGen.CreatePOBJsFromTriangleList(newVerties, attrs, dl.Envelopes); foreach (var p in newpobj.List) { p.Flags |= POBJ_FLAG.CULLBACK | POBJ_FLAG.UNKNOWN1; } if (newDOBJ.Pobj == null) { newDOBJ.Pobj = newpobj; } else { newDOBJ.Pobj.Add(newpobj); } } pobjGen.SaveChanges(); return(newDOBJ); }
/// <summary> /// /// </summary> /// <param name="group"></param> /// <returns></returns> public static HSD_JOBJ GenerateModel(SSFGroup group) { var jobj = new HSD_JOBJ() { Flags = JOBJ_FLAG.CLASSICAL_SCALING, SX = 1, SY = 1, SZ = 1 }; if (group.Lines.Count == 0) { return(jobj); } var attributes = new GXAttribName[] { GXAttribName.GX_VA_POS, GXAttribName.GX_VA_NRM, GXAttribName.GX_VA_NULL }; var triangleList = new List <GX_Vertex>(); foreach (var l in group.Lines) { var v1 = group.Vertices[l.Vertex1]; var v2 = group.Vertices[l.Vertex2]; var nrm = new OpenTK.Vector3(v1.X - v2.X, v1.Y - v2.Y, 0).Normalized(); var normal = new GXVector3(nrm.Y, -nrm.X, nrm.Z); triangleList.Add(new GX_Vertex() { POS = new GXVector3(v1.X, v1.Y, 5), NRM = normal }); triangleList.Add(new GX_Vertex() { POS = new GXVector3(v1.X, v1.Y, -5), NRM = normal }); triangleList.Add(new GX_Vertex() { POS = new GXVector3(v2.X, v2.Y, 5), NRM = normal }); triangleList.Add(new GX_Vertex() { POS = new GXVector3(v2.X, v2.Y, -5), NRM = normal }); triangleList.Add(new GX_Vertex() { POS = new GXVector3(v2.X, v2.Y, 5), NRM = normal }); triangleList.Add(new GX_Vertex() { POS = new GXVector3(v1.X, v1.Y, -5), NRM = normal }); } var gen = new HSDRaw.Tools.POBJ_Generator(); jobj.Dobj = new HSD_DOBJ() { Mobj = new HSD_MOBJ() { RenderFlags = RENDER_MODE.DIFFUSE, Material = new HSD_Material() { Alpha = 1, AmbientColor = System.Drawing.Color.Gray, DiffuseColor = System.Drawing.Color.Gray, SpecularColor = System.Drawing.Color.White, } }, Pobj = gen.CreatePOBJsFromTriangleList(triangleList, attributes, null) }; gen.SaveChanges(); Console.WriteLine(gen.CreatePOBJsFromTriangleList(triangleList, attributes, null).Attributes); return(jobj); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="cc"></param> /// <returns></returns> private static int CompCountToInt(GXAttribName name, GXCompCnt cc) { switch (name) { case GXAttribName.GX_VA_POS: switch (cc) { case GXCompCnt.PosXY: return(2); case GXCompCnt.PosXYZ: return(3); } break; case GXAttribName.GX_VA_NRM: switch (cc) { case GXCompCnt.NrmXYZ: case GXCompCnt.NrmNBT: return(3); case GXCompCnt.NrmNBT3: // ?? return(3); } break; case GXAttribName.GX_VA_NBT: switch (cc) { case GXCompCnt.NrmNBT: return(9); case GXCompCnt.NrmNBT3: return(9); } break; case GXAttribName.GX_VA_TEX0: case GXAttribName.GX_VA_TEX1: case GXAttribName.GX_VA_TEX2: case GXAttribName.GX_VA_TEX3: case GXAttribName.GX_VA_TEX4: case GXAttribName.GX_VA_TEX5: case GXAttribName.GX_VA_TEX6: case GXAttribName.GX_VA_TEX7: switch (cc) { case GXCompCnt.TexST: return(2); case GXCompCnt.TexS: return(1); } break; case GXAttribName.GX_VA_CLR0: case GXAttribName.GX_VA_CLR1: if (cc == GXCompCnt.ClrRGBA) { return(4); } if (cc == GXCompCnt.ClrRGB) { return(3); } break; } return(0); }
/// <summary> /// Test for rebuilding pobjs from scratch /// </summary> /// <param name="path"></param> public static void RebuildPOBJs(string path) { HSDRawFile file = new HSDRawFile(path); var rootJOBJ = (HSD_JOBJ)(file.Roots[0].Data); var compressor = new POBJ_Generator(); foreach (var jobj in rootJOBJ.BreathFirstSearch) { if (jobj.Dobj != null) { foreach (var dobj in jobj.Dobj.List) { if (dobj.Pobj != null) { GXAttribName[] attributes = null; if (attributes == null) { attributes = new GXAttribName[dobj.Pobj.Attributes.Length - 1]; for (int i = 0; i < attributes.Length; i++) { attributes[i] = dobj.Pobj.Attributes[i].AttributeName; } } List <GX_Vertex> triList = new List <GX_Vertex>(); List <HSD_JOBJ[]> bones = new List <HSD_JOBJ[]>(); List <float[]> weights = new List <float[]>(); foreach (var pobj in dobj.Pobj.List) { var dl = pobj.ToDisplayList(); int off = 0; foreach (var pri in dl.Primitives) { var strip = dl.Vertices.GetRange(off, pri.Count); if (pri.PrimitiveType == GXPrimitiveType.TriangleStrip) { TriangleConverter.StripToList(strip, out strip); } if (pri.PrimitiveType == GXPrimitiveType.Quads) { TriangleConverter.QuadToList(strip, out strip); } off += pri.Count; //if(pobj.Flags.HasFlag(POBJ_FLAG.ENVELOPE)) { triList.AddRange(strip); foreach (var v in strip) { if (dl.Envelopes.Count > 0) { var en = dl.Envelopes[v.PNMTXIDX / 3]; HSD_JOBJ[] b = en.JOBJs; float[] w = en.Weights; bones.Add(b); weights.Add(w); } else { bones.Add(new HSD_JOBJ[0]); weights.Add(new float[0]); } } } } } dobj.Pobj = compressor.CreatePOBJsFromTriangleList(triList, attributes, bones, weights); /*List<GX_Vertex> triList = new List<GX_Vertex>(); * foreach (var pobj in dobj.Pobj.List) * { * var dl = pobj.DisplayList; * var newPrimGroup = new List<GX_PrimitiveGroup>(); * int offset = 0; * foreach (var g in dl.Primitives) * { * GX_Vertex[] strip = new GX_Vertex[g.Count]; * for (int i = 0; i < g.Count; i++) * strip[i] = dl.Vertices[offset + i]; * newPrimGroup.Add(compressor.Compress(g.PrimitiveType, strip, pobj.Attributes)); * offset += g.Count; * } * dl.Primitives = newPrimGroup; * pobj.DisplayList = dl; * }*/ } } } } compressor.SaveChanges(); file.Save(path + "_rebuilt.dat"); }