public NUD toNUD() { NUD n = new NUD(); n.hasBones = false; foreach (OBJObject o in objects) { NUD.Mesh m = new NUD.Mesh(); m.Text = o.name; m.singlebind = -1; m.boneflag = 0x08; foreach (OBJGroup g in o.groups) { if (g.v.Count == 0) { continue; } NUD.Polygon p = new NUD.Polygon(); m.Nodes.Add(p); m.Nodes.Add(p); p.AddDefaultMaterial(); p.vertSize = 0x06; p.UVSize = 0x10; p.polflag = 0x00; Dictionary <int, int> collected = new Dictionary <int, int>(); for (int i = 0; i < g.v.Count; i++) { p.vertexIndices.Add(p.vertices.Count); NUD.Vertex v = new NUD.Vertex(); p.vertices.Add(v); if (g.v.Count > i) { v.pos = this.v[g.v[i]] + Vector3.Zero; } if (g.vn.Count > i) { v.nrm = vn[g.vn[i]] + Vector3.Zero; } if (g.vt.Count > i) { v.uv.Add(vt[g.vt[i]] + Vector2.Zero); } } } if (m.Nodes.Count > 0) { n.Nodes.Add(m); } } n.OptimizeFileSize(); n.UpdateRenderMeshes(); return(n); }
public static void ArrangeBones(VBN vbn, NUD nud) { Dictionary <int, int> boneReorder = new Dictionary <int, int>(); int i = 0; for (i = 0; i < boneOrder.Count; i++) { int j = 0; for (j = 0; j < vbn.bones.Count; j++) { if (vbn.bones[j].Text.Equals(boneOrder[i])) { break; } } boneReorder.Add(j, i); } // get rest of the bones for (int j = 0; j < vbn.bones.Count; j++) { if (!boneReorder.Keys.Contains(j)) { boneReorder.Add(j, i++); } } // reorder vbn Bone[] nList = new Bone[vbn.bones.Count]; foreach (int k in boneReorder.Keys) { nList[boneReorder[k]] = vbn.bones[k]; //if (new string(vbn.bones[k].boneName).Equals("RotN")) vbn.bones[k].parentIndex = 0; if (vbn.bones[k].parentIndex != -1 && vbn.bones[k].parentIndex != 0x0FFFFFFF) { vbn.bones[k].parentIndex = boneReorder[vbn.bones[k].parentIndex]; } } vbn.bones.Clear(); vbn.bones.AddRange(nList); vbn.reset(); // now fix the nud foreach (NUD.Mesh mesh in nud.Nodes) { foreach (NUD.Polygon poly in mesh.Nodes) { foreach (NUD.Vertex v in poly.vertices) { for (int k = 0; k < v.boneIds.Count; k++) { v.boneIds[k] = boneReorder[v.boneIds[k]]; } } } } nud.UpdateRenderMeshes(); }
// I'm completely totally serious public static NUD Create(VBN vbn) { Dictionary <string, string> files = new Dictionary <string, string>(); ZipArchive zip = ZipFile.OpenRead("lib\\Skapon.zip"); Random random = new Random(); int randomNumber = random.Next(0, 0xFFFFFF); NUT nut = new NUT(); foreach (ZipArchiveEntry e in zip.Entries) { byte[] b; using (BinaryReader br = new BinaryReader(e.Open())) { b = br.ReadBytes((int)e.Length); } var stream = new StreamReader(new MemoryStream(b)); string s = stream.ReadToEnd(); files.Add(e.Name, s); if (e.Name.EndsWith(".dds")) { NutTexture tex = new DDS(new FileData(b)).ToNutTexture(); nut.Nodes.Add(tex); tex.HashId = 0x40000000 + randomNumber; nut.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex)); } } NUD nud = new NUD(); NUD.Mesh head = new NUD.Mesh(); nud.Nodes.Add(head); head.Text = "Skapon"; head.Nodes.Add(setToBone(scale(readPoly(files["head.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("HeadN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["body.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("BustN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["hand.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("RHandN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["hand.obj"]), -1, -1, 1), vbn.bones[vbn.boneIndex("LHandN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["foot.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("RFootJ")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["foot.obj"]), -1, -1, -1), vbn.bones[vbn.boneIndex("LFootJ")], vbn)); foreach (NUD.Polygon p in head.Nodes) { p.materials[0].textures[0].hash = 0x40000000 + randomNumber; } nud.UpdateRenderMeshes(); return(nud); }
public void Move(int type, float move) { // move mesh over foreach (NUD.Polygon p in mesh.Nodes) { foreach (NUD.Vertex v in p.vertices) { // Rotate the mesh normals as well to preserve proper normal direction. switch (type) { case 1: v.pos.X += move; break; case 2: v.pos.Y += move; break; case 3: v.pos.Z += move; break; case 4: v.pos = Vector3.TransformVector(v.pos, Matrix4.CreateRotationX(move * ((float)Math.PI / 180))); v.nrm = Vector3.TransformVector(v.nrm, Matrix4.CreateRotationX(move * ((float)Math.PI / 180))).Normalized(); break; case 5: v.pos = Vector3.TransformVector(v.pos, Matrix4.CreateRotationY(move * ((float)Math.PI / 180))); v.nrm = Vector3.TransformVector(v.nrm, Matrix4.CreateRotationY(move * ((float)Math.PI / 180))).Normalized(); break; case 6: v.pos = Vector3.TransformVector(v.pos, Matrix4.CreateRotationZ(move * ((float)Math.PI / 180))); v.nrm = Vector3.TransformVector(v.nrm, Matrix4.CreateRotationZ(move * ((float)Math.PI / 180))).Normalized(); break; case 7: v.pos = Vector3.Multiply(v.pos, move); break; } } } NUD n = (NUD)mesh.Parent; n.UpdateRenderMeshes(); MainForm.Instance.GetActiveModelViewport()?.glViewport?.Invalidate(); }
public static void effectiveScale(NUD nud, VBN vbn, Matrix4 sca) { foreach (Bone b in vbn.bones) { Vector3 pos = Vector3.TransformVector(new Vector3(b.position[0], b.position[1], b.position[2]), sca); b.position[0] = pos.X; b.position[1] = pos.Y; b.position[2] = pos.Z; } vbn.reset(); foreach (NUD.Mesh mesh in nud.Nodes) { foreach (NUD.Polygon poly in mesh.Nodes) { foreach (NUD.Vertex v in poly.vertices) { v.pos = Vector3.TransformVector(v.pos, sca); } } } nud.UpdateRenderMeshes(); }
public static void MakePichu(string path = "C:\\Pichu\\") { if (!path.EndsWith("\\")) { path += "\\"; } DAT dat = new DAT(); dat.Read(new FileData(path + "PlPcNr.dat")); dat.PreRender(); dat.ExportTextures(path, 0x401B1000); BoneNameFix(dat.bones); // model-------------------------------------------------------- ModelContainer converted = dat.wrapToNUD(); NUD nud = converted.NUD; float sca = 0.6f; removeLowPolyNr(nud); nud.UpdateRenderMeshes(); //Runtime.ModelContainers.Add(converted); //------------------------------------------------- Runtime.TargetVBN = converted.VBN; MainForm.HashMatch(); Dictionary <string, SkelAnimation> anims = DAT_Animation.LoadAJ(path + "PlPcAJ.dat", converted.VBN); //ArrangeBones(converted.vbn, converted.nud); // note bone 40 - 51 is disabled for pika foreach (string an in anims.Keys) { effectiveScale(anims[an], Matrix4.CreateTranslation(0, 0, 0) * Matrix4.CreateScale(sca, sca, sca)); } effectiveScale(converted.NUD, converted.VBN, Matrix4.CreateTranslation(0, 0, 0) * Matrix4.CreateScale(sca, sca, sca)); Directory.CreateDirectory(path + "build\\model\\body\\c00\\"); nud.Save(path + "build\\model\\body\\c00\\model.nud"); converted.VBN.Endian = Endianness.Little; converted.VBN.Save(path + "build\\model\\body\\c00\\model.vbn"); PAC org = new PAC(); PAC npac = new PAC(); org.Read(path + "main.pac"); foreach (string key in org.Files.Keys) { byte[] d = org.Files[key]; foreach (string an in anims.Keys) { string name = an.Replace("PlyPichu5K_Share_ACTION_", "").Replace("_figatree", ""); if (key.Contains(name)) { Console.WriteLine("Matched " + name + " with " + key); if (!anims[an].getNodes(true).Contains(0) && !key.Contains("Cliff")) { KeyNode node = anims[an].getNode(0, 0); node.t_type = 1; } d = OMOOld.createOMO(anims[an], converted.VBN); break; } } npac.Files.Add(key, d); } Directory.CreateDirectory(path + "build\\motion\\"); npac.Save(path + "build\\motion\\main.pac"); /*FileOutput omo = new FileOutput(); * converted.vbn.reset(); * converted.vbn.totalBoneCount = (uint)converted.vbn.bones.Count; * omo.writeBytes(OMO.createOMO(anims["PlyPichu5K_Share_ACTION_Wait1_figatree"], converted.vbn)); * omo.save(path + "PlyPichu5K_Share_ACTION_Wait1_figatree.omo");*/ }
public static NUD toNUD(string fname) { StreamReader reader = File.OpenText(fname); string line; string current = ""; NUD nud = new NUD(); while ((line = reader.ReadLine()) != null) { line = Regex.Replace(line, @"\s+", " "); string[] args = line.Replace(";", "").TrimStart().Split(' '); if (args[0].Equals("triangles") || args[0].Equals("end")) { current = args[0]; continue; } if (current.Equals("triangles")) { string meshName = args[0]; if (args[0].Equals("")) { continue; } for (int j = 0; j < 3; j++) { line = reader.ReadLine(); line = Regex.Replace(line, @"\s+", " "); args = line.Replace(";", "").TrimStart().Split(' '); // read triangle strip int parent = int.Parse(args[0]); NUD.Vertex vert = new NUD.Vertex(); vert.pos = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])); vert.nrm = new Vector3(float.Parse(args[4]), float.Parse(args[5]), float.Parse(args[6])); vert.uv.Add(new Vector2(float.Parse(args[7]), float.Parse(args[8]))); int wCount = int.Parse(args[9]); int w = 10; for (int i = 0; i < wCount; i++) { vert.boneIds.Add(int.Parse(args[w++])); vert.boneWeights.Add(float.Parse(args[w++])); } NUD.Mesh mes = null; foreach (NUD.Mesh m in nud.Nodes) { if (m.Text.Equals(meshName)) { mes = m; } } if (mes == null) { mes = new NUD.Mesh(); mes.Text = meshName; nud.Nodes.Add(mes); } if (mes.Nodes.Count == 0) { NUD.Polygon poly = new NUD.Polygon(); poly.AddDefaultMaterial(); mes.Nodes.Add(poly); } { ((NUD.Polygon)mes.Nodes[0]).vertexIndices.Add(((NUD.Polygon)mes.Nodes[0]).vertices.Count); ((NUD.Polygon)mes.Nodes[0]).vertices.Add(vert); } } } } nud.OptimizeFileSize(); nud.UpdateRenderMeshes(); return(nud); }