Пример #1
0
        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.faces.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.UpdateVertexData();

            return(n);
        }
Пример #2
0
        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.UpdateVertexData();
        }
Пример #3
0
        // 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)).toNUT_Texture();
                    nut.Nodes.Add(tex);
                    tex.HASHID = 0x40000000 + randomNumber;
                    nut.draw.Add(tex.HASHID, NUT.loadImage(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.UpdateVertexData();

            return(nud);
        }
Пример #4
0
        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.UpdateVertexData();
        }
Пример #5
0
        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.UpdateVertexData();
        }
Пример #6
0
        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]).faces.Add(((NUD.Polygon)mes.Nodes[0]).vertices.Count);
                            ((NUD.Polygon)mes.Nodes[0]).vertices.Add(vert);
                        }
                    }
                }
            }

            nud.OptimizeFileSize();
            nud.UpdateVertexData();
            return(nud);
        }
        public void Apply(NUD nud)
        {
            nud.GenerateBoundingBoxes();
            Matrix4 rotXBy90 = Matrix4.CreateRotationX(0.5f * (float)Math.PI);
            float   scale    = 1f;
            bool    hasScale = float.TryParse(scaleTB.Text, out scale);

            bool checkedMeshName = false;
            bool fixMeshName     = false;

            bool hasShownShadowWarning = false;

            foreach (NUD.Mesh mesh in nud.Nodes)
            {
                if (BoneTypes[(string)boneTypeComboBox.SelectedItem] == BoneTypes["None"])
                {
                    mesh.boneflag = 0;
                }

                if (!checkedMeshName)
                {
                    checkedMeshName = true;
                    if (mesh.Text.Length > 5)
                    {
                        string sub = mesh.Text.Substring(0, 5);
                        int    a   = 0;
                        if (sub.StartsWith("_") && sub.EndsWith("_") && int.TryParse(sub.Substring(1, 3), out a))
                        {
                            fixMeshName = DialogResult.Yes == MessageBox.Show("Detected mesh names that start with \"_###_\". Would you like to fix this?\nIt is recommended that you select \"Yes\".", "Mesh Name Fix", MessageBoxButtons.YesNo);
                        }
                    }
                }
                if (fixMeshName)
                {
                    if (mesh.Text.Length > 5)
                    {
                        mesh.Text = mesh.Text.Substring(5);
                    }
                }

                foreach (NUD.Polygon poly in mesh.Nodes)
                {
                    if (BoneTypes[(string)boneTypeComboBox.SelectedItem] == BoneTypes["None"])
                    {
                        poly.polflag = 0;
                    }

                    if (smoothNrmCB.Checked)
                    {
                        poly.SmoothNormals();
                    }

                    // Set the vertex size before tangent/bitangent calculations.
                    if (poly.vertSize == (int)NUD.Polygon.VertexTypes.NormalsHalfFloat) // what is this supposed to mean?
                    {
                        poly.vertSize = 0;
                    }
                    else
                    {
                        poly.vertSize = BoneTypes[(string)boneTypeComboBox.SelectedItem] | VertexTypes[(string)vertTypeComboBox.SelectedItem];
                    }

                    poly.CalculateTangentBitangent();

                    int vertSizeShadowWarning = (int)NUD.Polygon.BoneTypes.HalfFloat | (int)NUD.Polygon.VertexTypes.NormalsTanBiTanHalfFloat;
                    if (!hasShownShadowWarning && poly.vertSize == vertSizeShadowWarning)
                    {
                        MessageBox.Show("Using \"" + (string)boneTypeComboBox.SelectedItem + "\" and \"" + (string)vertTypeComboBox.SelectedItem + "\" can make shadows not appear in-game.",
                                        "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        hasShownShadowWarning = true;
                    }

                    if (stageMatCB.Checked)
                    {
                        poly.materials.Clear();
                        poly.materials.Add(NUD.Material.GetStageDefault());
                    }

                    foreach (NUD.Vertex v in poly.vertices)
                    {
                        //Scroll UVs V by -1
                        if (transUvVerticalCB.Checked)
                        {
                            for (int i = 0; i < v.uv.Count; i++)
                            {
                                v.uv[i] = new Vector2(v.uv[i].X, v.uv[i].Y + 1);
                            }
                        }

                        // Flip UVs
                        if (flipUVCB.Checked)
                        {
                            for (int i = 0; i < v.uv.Count; i++)
                            {
                                v.uv[i] = new Vector2(v.uv[i].X, 1 - v.uv[i].Y);
                            }
                        }

                        // Halve vertex colors
                        if (vertColorDivCB.Checked)
                        {
                            for (int i = 0; i < 3; i++)
                            {
                                v.color[i] = v.color[i] / 2;
                            }
                        }

                        // Set vertex colors to white.
                        if (vertcolorCB.Checked)
                        {
                            v.color = new Vector4(127, 127, 127, 127);
                        }

                        // Rotate 90 degrees.
                        if (rotate90CB.Checked)
                        {
                            v.pos = Vector3.TransformPosition(v.pos, rotXBy90);
                            v.nrm = Vector3.TransformNormal(v.nrm, rotXBy90);
                        }

                        // Scale.
                        if (scale != 1f)
                        {
                            v.pos = Vector3.Multiply(v.pos, scale);
                        }
                    }
                }
            }

            nud.UpdateVertexData();
        }
Пример #8
0
        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.UpdateVertexData();

            //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");*/
        }