Ejemplo n.º 1
0
        public void ReadFromStream(TextReader sr)
        {
            Clear();
            m_RootElements = ParseContent(sr.ReadToEnd());

            if (!m_RootElements.Contains("objects"))
            {
                throw new Exception("Invalid PBX project file: no objects element");
            }

            var objects = m_RootElements["objects"].AsDict();

            m_RootElements.Remove("objects");
            m_RootElements.SetString("objects", "OBJMARKER");

            if (m_RootElements.Contains("objectVersion"))
            {
                m_ObjectVersion = m_RootElements["objectVersion"].AsString();
                m_RootElements.Remove("objectVersion");
            }

            var    allGuids        = new List <string>();
            string prevSectionName = null;

            foreach (var kv in objects.values)
            {
                allGuids.Add(kv.Key);
                var el = kv.Value;

                if (!(el is PBXElementDict) || !el.AsDict().Contains("isa"))
                {
                    m_UnknownObjects.values.Add(kv.Key, el);
                    continue;
                }
                var dict        = el.AsDict();
                var sectionName = dict["isa"].AsString();

                if (m_Section.ContainsKey(sectionName))
                {
                    var section = m_Section[sectionName];
                    section.AddObject(kv.Key, dict);
                }
                else
                {
                    UnknownSection section;
                    if (m_UnknownSections.ContainsKey(sectionName))
                    {
                        section = m_UnknownSections[sectionName];
                    }
                    else
                    {
                        section = new UnknownSection(sectionName);
                        m_UnknownSections.Add(sectionName, section);
                    }
                    section.AddObject(kv.Key, dict);

                    // update section order
                    if (!m_SectionOrder.Contains(sectionName))
                    {
                        int pos = 0;
                        if (prevSectionName != null)
                        {
                            // this never fails, because we already added any previous unknown sections
                            // to m_SectionOrder
                            pos  = m_SectionOrder.FindIndex(x => x == prevSectionName);
                            pos += 1;
                        }
                        m_SectionOrder.Insert(pos, sectionName);
                    }
                }
                prevSectionName = sectionName;
            }
            RepairStructure(allGuids);
            RefreshAuxMaps();
        }
Ejemplo n.º 2
0
        public void ImportFromPsk(string path, int lod)
        {
            DebugOutput.Clear();
            DebugOutput.PrintLn("Loading \"" + Path.GetFileName(path) + "\"...");
            psk = new PSKFile();                                        //source psk object
            psk.ImportPSK(path);                                        //load file
            LOD l = Mesh.LODs[lod];                                     //target LOD object
            l.Indexes = new List<ushort>();                             //Init
            l.Headers = new List<LODHeader>();
            l.UnkSec1 = new List<UnknownSection>();
            DebugOutput.PrintLn("Creating bone conversion table...");
            List<int> pskBone2skm = new List<int>();                    //to convert psk boneindex to skm boneindex
            foreach (PSKFile.PSKBone b in psk.psk.bones)                //loop all psk bones
                for (int i = 0; i < Mesh.Bones.Count; i++)              //for each loop all skm bones
                    if (b.name.TrimEnd(' ') == pcc.getNameEntry(Mesh.Bones[i].name)) //if match, ...
                    {
                        pskBone2skm.Add(i);                             //...then add
                        if (MPOpt.SKM_importbones)
                        {
                            Bone t = Mesh.Bones[i];
                            t.position = b.location.ToVector3();
                            t.orientation = new Quad(b.rotation.ToVector4());
                            t.position.Y *= -1;
                            t.orientation.y *= -1;
                            if (i == 0)
                                t.orientation.w *= -1;
                            Mesh.Bones[i] = t;
                        }
                        break;                                          //break search for match on this bone
                    }
            DebugOutput.PrintLn("Importing Materials...");
            if (psk.psk.materials.Count > Mesh.Materials.Count())       //If more Materials are needed to import
            {
                int count = psk.psk.materials.Count - Mesh.Materials.Count();                
                int mat = Mesh.Materials[0];
                for (int i = 0; i < count; i++)
                    Mesh.Materials.Add(mat);                            //Fill up with first material used
            }
            l.UnkCount1 = psk.psk.materials.Count;
            DebugOutput.PrintLn("Importing Indexes...");
            int facesoffset = 0;                                        //faceoffset for current section
            for (int i = 0; i < psk.psk.materials.Count; i++)           //Section count = Material Count
            {
                int count = 0;                                          //Face count of this section
                LODHeader h = new LODHeader();                          //Header object for Current Section
                h.index = (ushort)i;                                    //yeah same as material
                h.matindex = (ushort)i;                                 //yeah same as material
                h.offset = (ushort)facesoffset;                         //offset in index buffer
                foreach (PSKFile.PSKFace f in psk.psk.faces)            //go through all faces 
                    if (f.material == i)                                //Face has current material?
                    {
                        l.Indexes.Add((ushort)psk.psk.edges[f.v0].index);                    //add corners to index buffer
                        l.Indexes.Add((ushort)psk.psk.edges[f.v2].index);
                        l.Indexes.Add((ushort)psk.psk.edges[f.v1].index);                    //culling swap
                        facesoffset += 3;                               //3 indexes added
                        count++;                                       //1 face added
                    }
                h.count = (uint)count;                                  //sum faces
                h.unk1 = 0;                                             //always zero
                l.Headers.Add(h);                                       //add new header

            }
            l.Edges = new List<Edge>();                                 //reset edge list, first step: import coords and UVS           
            DebugOutput.PrintLn("Importing Vertices and UVs...");
            for (int i = 0; i < psk.psk.points.Count; i++)               //loop all edges/vertices in psk
            {
                Edge ne = new Edge();                                   //the new skm edge
                PSKFile.PSKEdge e = new PSKFile.PSKEdge();
                PSKFile.PSKPoint p = psk.psk.points[i];                 //actual point from psk
                foreach(PSKFile.PSKEdge t in psk.psk.edges)
                    if (t.index == i)
                    {
                        e = t;
                        break;
                    }
                ne.Position = p.ToVector3();                            //set coords&UVs
                ne.Position.Y *= -1;                                    //flip Y axis                  
                ne.UV = new Vector2(e.U, e.V); //offsets for light fix
                ne.Influences = new List<Influence>();                  //prepare
                foreach (PSKFile.PSKWeight w in psk.psk.weights)
                    if (w.point == i)
                        ne.Influences.Add(new Influence(w.weight, pskBone2skm[w.bone]));
                ne.Unk1 = 0;                                            //tangent space quad1
                ne.Unk2 = 0;                                            //tangent space quad2
                l.Edges.Add(ne);
            }
            DebugOutput.PrintLn("Adding Dup Influences...");
            int ccnt = 0;
            int ccnt2 = 0;
            foreach (Edge e in l.Edges)
            {
                bool done = false;
                if (e.Influences.Count() == 0)
                {
                    foreach (Edge e2 in l.Edges)
                        if (e2.Position == e.Position && e2.Influences.Count() != 0 && !done)
                        {
                            foreach (Influence i in e2.Influences)
                            {
                                Influence ni;
                                ni.bone = i.bone;
                                ni.weight = i.weight;
                                e.Influences.Add(ni);
                            }
                            done = true;
                            ccnt2++;
                        }
                        else if (done)
                            break;
                    ccnt++;
                }
            }
            for (int i = 0; i < l.Edges.Count; i++)
            {
                List<Influence> tinf = new List<Influence>();
                for (int j = 0; j < l.Edges[i].Influences.Count; j++)
                    if (l.Edges[i].Influences[j].weight > 0)
                        tinf.Add(l.Edges[i].Influences[j]);
                Edge e = l.Edges[i];
                e.Influences = tinf;
                l.Edges[i] = e;
            }
            List<int> tempidx = new List<int>();
            for (int i = 0; i < l.Edges.Count; i++)
                if (l.Edges[i].Influences.Count == 1)
                    tempidx.Add(i);
            for (int i = 0; i < l.Edges.Count; i++)
                if (l.Edges[i].Influences.Count > 1)
                    tempidx.Add(i);
            List<Edge> tmpedges = new List<Edge>();
            foreach (int n in tempidx)
                tmpedges.Add(l.Edges[n]);
            l.Edges = tmpedges;
            for(int i=0;i<l.Indexes.Count;i++)
                for(int j=0;j<tmpedges.Count;j++)
                    if (tempidx[j] == l.Indexes[i])
                    {
                        l.Indexes[i] = (ushort)j;
                        break;                        
                    }
            DebugOutput.PrintLn(ccnt + " " + ccnt2 + " Filling up Influences...");
            foreach (Edge e in l.Edges)                                 //loop all edges and fill up influences to 4
            {
                int count = e.Influences.Count();                       //current influence count
                for (int i = count; i < 4; i++)                         //add until 4
                    e.Influences.Add(new Influence(0, 0));              //add placeholder
            }
            DebugOutput.PrintLn("Creating active bone list...");
            l.ActiveBones = new List<byte>();                           //Init List, Get Active Bone List
            l.ActiveBones.Add(0);                                       //add god node
            foreach (Edge e in l.Edges)                                 //loop all edges
                for (int i = 0; i < 4; i++)                                    //and each influence
                    if (e.Influences[i].weight != 0)                    //if has influence
                    {
                        byte bone = e.Influences[i].bone;               //get bone
                        bool found = false;                             //search if already in list
                        for (int j = 0; j < l.ActiveBones.Count; j++)
                            if (l.ActiveBones[j] == bone)
                                found = true;
                        if (!found)                                     //if not in list, add
                            l.ActiveBones.Add(bone);
                    }
            l.ActiveBones.Sort();                                       //Sort list
            int lastbone = l.ActiveBones[l.ActiveBones.Count - 1];
            l.ActiveBones = new List<byte>();
            for (byte i = 0; i <= lastbone; i++)
                l.ActiveBones.Add(i);
            DebugOutput.PrintLn("Creating sub bone lists...");
            foreach (LODHeader h in l.Headers)                          //Get sub bonelists, loop each section
            {
                UnknownSection s = new UnknownSection();                //init
                s.Unkn = new byte[24];                                  //zero for now, !!!TODO!!!
                s.Indexes = new List<ushort>();
                foreach (byte b in l.ActiveBones)
                    s.Indexes.Add(b);                                   //sort list
                l.UnkSec1.Add(s);                                       //add this section
            }
            DebugOutput.PrintLn("Creating unknown bone list...");
            l.UnkIndexes1 = new List<ushort>();
            foreach (byte b in l.ActiveBones)
                l.UnkIndexes1.Add(b);
            int edgeoffset = 0;
            DebugOutput.PrintLn("Creating unknown sections...");
            for (int i = 0; i < l.Headers.Count; i++)                   //update values in unknown section
            {
                LODHeader h = l.Headers[i];
                int pos = (int)h.offset;
                int maxsimple = -1;
                int maxmulti = -1;
                int minsimple = l.Edges.Count;
                int minmulti = l.Edges.Count;
                int lensimple = 0, lenmulti = 0;
                for (int j = 0; j < h.count * 3; j++)                   //determine min,max edge indexes
                {
                    Edge e = l.Edges[l.Indexes[pos]];
                    int index = l.Indexes[pos];
                    int count = 0;
                    foreach (Influence inf in e.Influences)
                        if (inf.weight != 0)
                            count++;
                    if (count == 0)
                    {
                        MessageBox.Show("Error: Found vertex without influences!");
                        return;
                    }
                    if (count == 1)
                    {
                        if (index < minsimple)
                            minsimple = index;
                        if (index > maxsimple)
                            maxsimple = index;
                    }
                    if (count > 1)
                    {
                        if (index < minmulti)
                            minmulti = index;
                        if (index > maxmulti)
                            maxmulti = index;
                    }
                    pos++;
                }
                lensimple = (maxsimple - minsimple) + 1;
                lenmulti = (maxmulti - minmulti) + 1;
                lensimple = Math.Max(lensimple, 0);
                lenmulti = Math.Max(lenmulti, 0);
                byte[] buff = BitConverter.GetBytes(lensimple);
                for (int j = 0; j < 4; j++)
                    l.UnkSec1[i].Unkn[j] = buff[j];
                buff = BitConverter.GetBytes(lenmulti);
                for (int j = 0; j < 4; j++)
                    l.UnkSec1[i].Unkn[j + 4] = buff[j];
                l.UnkSec1[i].Unkn[8] = 4;
                int sum = lensimple + lenmulti;
                edgeoffset += sum;
                if (i == l.Headers.Count - 1)
                {
                    buff = BitConverter.GetBytes(edgeoffset);
                    for (int j = 0; j < 4; j++)
                        l.UnkSec1[i].Unkn[j + 16] = buff[j];
                }
                else
                {
                    buff = BitConverter.GetBytes(edgeoffset);
                    for (int j = 0; j < 4; j++)
                        l.UnkSec1[i].Unkn[j + 12] = buff[j];
                }
            }
            DebugOutput.PrintLn("Calculating 4D tangent space quaternions...");
            CalcTangentSpace2(l);                                      //Calc 4D Tangents
            DebugOutput.PrintLn("Done.");
            DebugOutput.PrintLn("Saving pcc...");
            Mesh.LODs[lod] = l;                                         //assign lod
        }
Ejemplo n.º 3
0
 public void ReadLODs()
 {
     int count = BitConverter.ToInt32(memory, readerpos);
     readerpos += 4;
     Mesh.LODs = new List<LOD>();
     for (int i = 0; i < count; i++)
     {
         LOD lod = new LOD();
         lod._offset = readerpos;
         lod.Headers = new List<LODHeader>();
         int sectioncount = BitConverter.ToInt32(memory, readerpos);
         readerpos += 4;
         for (int j = 0; j < sectioncount; j++)
         {
             LODHeader lodsec = new LODHeader();
             lodsec.matindex = BitConverter.ToUInt16(memory, readerpos);
             lodsec.index = BitConverter.ToUInt16(memory, readerpos + 2);                    
             lodsec.offset = BitConverter.ToUInt32(memory, readerpos + 4);
             lodsec.count = BitConverter.ToUInt16(memory, readerpos + 8);
             lodsec.unk1 = BitConverter.ToUInt16(memory, readerpos + 10);
             readerpos += 12;
             lod.Headers.Add(lodsec);
         }
         int indexsize = BitConverter.ToInt32(memory, readerpos);
         int indexcount = BitConverter.ToInt32(memory, readerpos + 4);
         readerpos += 8;
         lod.Indexes = new List<ushort>();
         for (int j = 0; j < sectioncount; j++)
         {
             for (int k = 0; k < lod.Headers[j].count * 3; k++)
             {
                 lod.Indexes.Add(BitConverter.ToUInt16(memory, readerpos));
                 readerpos += 2;
             }
         }
         indexcount = BitConverter.ToInt32(memory, readerpos); // ?? SoftVertices ??
         readerpos += 4;
         if (indexcount != 0)
         {
             MessageBox.Show("Not implemented!");
             return;
         }
         indexcount = BitConverter.ToInt32(memory, readerpos); // ?? RigidVertices ??
         readerpos += 4;
         lod.UnkIndexes1 = new List<ushort>();
         for (int k = 0; k < indexcount; k++)
         {
             lod.UnkIndexes1.Add(BitConverter.ToUInt16(memory, readerpos));
             readerpos += 2;
         }
         indexcount = BitConverter.ToInt32(memory, readerpos); // ?? ShadowIndices ??
         readerpos += 4;
         if (indexcount != 0)
         {
             MessageBox.Show("Not implemented!");
             return;
         }
         lod.UnkCount1 = BitConverter.ToInt32(memory, readerpos); // ?? Sections ??
         readerpos += 4;
         lod.UnkIndexes2 = new List<UInt32>();
         for (int k = 0; k < 3; k++)                         // ?? Rot/Loc ??
         {
             lod.UnkIndexes2.Add(BitConverter.ToUInt32(memory, readerpos));
             readerpos += 4;
         }
         lod.UnkSec1 = new List<UnknownSection>();
         for (int k = 0; k < lod.UnkCount1; k++)    // ?? Sections ?? Materials ??
         {
             UnknownSection unk = new UnknownSection();
             indexcount = BitConverter.ToInt32(memory, readerpos);
             readerpos += 4;
             unk.Indexes = new List<ushort>();
             for (int l = 0; l < indexcount; l++) // ?? active bones ??
             {
                 unk.Indexes.Add(BitConverter.ToUInt16(memory, readerpos));
                 readerpos += 2;
             }
             unk.Unkn = new byte[24];
             for (int l = 0; l < 24; l++)
                 unk.Unkn[l] = memory[readerpos + l];
             readerpos += 24;
             lod.UnkSec1.Add(unk);
         }
         indexcount = BitConverter.ToInt32(memory, readerpos);
         readerpos += 4;
         lod.ActiveBones = new List<byte>();
         for (int k = 0; k < indexcount; k++)
             lod.ActiveBones.Add(memory[readerpos + k]);
         readerpos += indexcount;
         lod.UnkSec2 = new byte[48];
         for (int k = 0; k < 48; k++)
             lod.UnkSec2[k] = memory[readerpos + k];
         readerpos += 48;
         indexsize = BitConverter.ToInt32(memory, readerpos);
         indexcount = BitConverter.ToInt32(memory, readerpos + 4);
         readerpos += 8;
         lod.Edges = new List<Edge>();
         for (int k = 0; k < indexcount; k++)
         {
             Edge e = new Edge();
             e._offset = readerpos;
             e.Unk1 = BitConverter.ToInt32(memory, readerpos);
             e.Unk2 = BitConverter.ToInt32(memory, readerpos + 4);
             e.Influences = new List<Influence>();
             for (int l = 0; l < 4; l++)
             {
                 Influence inf = new Influence();
                 inf.bone = memory[readerpos + 8 + l];
                 inf.weight = memory[readerpos + 12 + l];
                 e.Influences.Add(inf);
             }
             e.Position = ReadVector(readerpos + 16);
             UInt16 u = BitConverter.ToUInt16(memory, readerpos + 28);
             UInt16 v = BitConverter.ToUInt16(memory, readerpos + 30); 
             e.UV = new Vector2(HalfToFloat(u), HalfToFloat(v));
             e._imported = false;
             lod.Edges.Add(e);
             readerpos += 32;
         }
         lod.unk2 = BitConverter.ToUInt32(memory, readerpos);
         readerpos += 4;                
         Mesh.LODs.Add(lod);
     }
 }
Ejemplo n.º 4
0
 private TreeNode ToTreeUnkSection(TreeNode t, UnknownSection sec)
 {
     TreeNode t1 = new TreeNode("Indexbuffer");
     for (int i = 0; i < sec.Indexes.Count; i++)
         t1.Nodes.Add(new TreeNode(i.ToString("d4") + " : " + sec.Indexes[i]));
     t.Nodes.Add(t1);            
     string s = "";
     for (int i = 0; i < 6; i++)
         s += BitConverter.ToInt32(sec.Unkn,i*4).ToString("d4") + " ";
     t.Nodes.Add(new TreeNode("Unknown : " + s));
     return t;
 }