コード例 #1
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
        void Export_IBUF_Main(StreamWriter w, IBUF ibuf, MLOD.Mesh mesh)
        {
            if (ibuf == null) { w.WriteLine("; ibuf is null"); w.WriteLine("ibuf 0"); return; }

            w.WriteLine(string.Format("ibuf {0}", mesh.PrimitiveCount));
            w.Export_IBUF(mpb, ibuf.GetIndices(mesh), IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType), mesh.PrimitiveCount);
        }
コード例 #2
0
        // Token: 0x06000004 RID: 4 RVA: 0x000022B8 File Offset: 0x000004B8
        private static bool convertP3dFile(string srcPath, string dstPath = null, bool allowOverwriting = false)
        {
            if (!allowOverwriting && srcPath == dstPath)
            {
                Trace.WriteLine("Overwriting the source file is disabled.");
                return(false);
            }
            Trace.WriteLine(string.Format("Reading the p3d ('{0}')...", srcPath));
            P3D instance = P3D.GetInstance(srcPath);

            if (instance is MLOD)
            {
                Trace.WriteLine(string.Format("'{0}' is already in editable MLOD format", srcPath));
            }
            else
            {
                ODOL odol = instance as ODOL;
                if (odol != null)
                {
                    Trace.WriteLine("ODOL was loaded successfully.");
                    Trace.WriteLine("Start conversion...");
                    MLOD mlod = Conversion.ODOL2MLOD(odol);
                    Trace.WriteLine("Conversion successful.");
                    string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(srcPath);
                    string directoryName            = Path.GetDirectoryName(srcPath);
                    dstPath = (dstPath ?? Path.Combine(directoryName, fileNameWithoutExtension + "_mlod.p3d"));
                    Trace.WriteLine("Saving...");
                    mlod.writeToFile(dstPath, allowOverwriting);
                    Trace.WriteLine(string.Format("MLOD successfully saved to '{0}'", dstPath));
                    return(true);
                }
                Trace.WriteLine(string.Format("'{0}' could not be loaded.", srcPath));
            }
            return(false);
        }
コード例 #3
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
        void Export_VBUF_Main(StreamWriter w, VBUF vbuf, VRTF vrtf, float[] uvScales, MLOD.Mesh mesh)
        {
            if (vbuf == null) { w.WriteLine("; vbuf is null"); w.WriteLine("vbuf 0"); return; }

            meshExpImp.ModelBlocks.Vertex[] av = vbuf.GetVertices(mesh, vrtf, uvScales);

            w.WriteLine(string.Format("vbuf {0}", av.Length));
            w.Export_VBUF(mpb, av, vrtf);
        }
コード例 #4
0
        public static void Export_SKIN(this StreamWriter w, MyProgressBar mpb, SKIN skin, MLOD.Mesh mesh)
        {
            if (skin == null) { w.WriteLine("; skin is null"); w.WriteLine("skin 0"); return; }

            if (!mesh.JointReferences.TrueForAll(x => skin.Bones.Exists(y => y.NameHash == x)))
            {
                w.WriteLine("; mesh.JointReferences references unknown bone.");
                w.WriteLine("skin 0");
                return;
            }
            List<uint> seen = new List<uint>();
            if (!mesh.JointReferences.TrueForAll(x => { if (seen.Contains(x)) return false; seen.Add(x); return true; }))
            {
                w.WriteLine("; mesh.JointReferences contains non-unique references.");
                w.WriteLine("skin 0");
                return;
            }
            seen = null;

            w.WriteLine(string.Format("skin {0}", skin.Bones.Count));

            mpb.Init("Export SKIN...", skin.Bones.Count);
            int i = 0;
            //Referenced bones
            //pre-20120601: foreach (var bone in skin.Bones.FindAll(x => mesh.JointReferences.Contains(x.NameHash)))
            foreach (var bone in ((IEnumerable<uint>)mesh.JointReferences).Select(hash => skin.Bones.Find(x => x.NameHash == hash)))
            {
                w.WriteLine(string.Format(
                    //"{0} {1:X8} {2:R} {3:R} {4:R} {5:R} {6:R} {7:R} {8:R} {9:R} {10:R} {11:R} {12:R} {13:R}",
                    "{0} {1:X8} {2:F6} {3:F6} {4:F6} {5:F6} {6:F6} {7:F6} {8:F6} {9:F6} {10:F6} {11:F6} {12:F6} {13:F6}",
                    i++,
                    bone.NameHash,
                    bone.InverseBindPose.Right.X, bone.InverseBindPose.Right.Y, bone.InverseBindPose.Right.Z, bone.InverseBindPose.Translate.X,
                    bone.InverseBindPose.Up.X, bone.InverseBindPose.Up.Y, bone.InverseBindPose.Up.Z, bone.InverseBindPose.Translate.Y,
                    bone.InverseBindPose.Back.X, bone.InverseBindPose.Back.Y, bone.InverseBindPose.Back.Z, bone.InverseBindPose.Translate.Z));
                mpb.Value++;
            }
            //Unreferenced bones
            foreach (var bone in skin.Bones.FindAll(x => !mesh.JointReferences.Contains(x.NameHash)))
            {
                w.WriteLine(string.Format(
                    //"{0} {1:X8} {2:R} {3:R} {4:R} {5:R} {6:R} {7:R} {8:R} {9:R} {10:R} {11:R} {12:R} {13:R}",
                    "{0} {1:X8} {2:F6} {3:F6} {4:F6} {5:F6} {6:F6} {7:F6} {8:F6} {9:F6} {10:F6} {11:F6} {12:F6} {13:F6}",
                    i++,
                    bone.NameHash,
                    bone.InverseBindPose.Right.X, bone.InverseBindPose.Right.Y, bone.InverseBindPose.Right.Z, bone.InverseBindPose.Translate.X,
                    bone.InverseBindPose.Up.X, bone.InverseBindPose.Up.Y, bone.InverseBindPose.Up.Z, bone.InverseBindPose.Translate.Y,
                    bone.InverseBindPose.Back.X, bone.InverseBindPose.Back.Y, bone.InverseBindPose.Back.Z, bone.InverseBindPose.Translate.Z));
                mpb.Value++;
            }
            w.Flush();
            mpb.Done();
        }
コード例 #5
0
 public static float[] GetUVScales(this GenericRCOLResource rcolResource, MLOD.Mesh mesh)
 {
     MATD matd = GetMATDforMesh(rcolResource, mesh.MaterialIndex);
     if (matd != null)
     {
         ShaderData data = (matd.Version < 0x0103 ? matd.Mtrl.SData : matd.Mtnf.SData).Find(x => x.Field == FieldType.UVScales);
         if (data != null)
         {
             if (data is ElementFloat3) { ElementFloat3 e = data as ElementFloat3; return new float[] { e.Data0, e.Data1, e.Data2, }; }
             else throw new InvalidOperationException(String.Format("Found UVScales of type '{0}'; expected 'ElementFloat3'.", data.GetType().Name));
         }
     }
     return new float[] { 1f / 32767f, 0f, 0f, };
 }
コード例 #6
0
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            if (mesh.GeometryStates.Count > 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: GeoStates follow IBUF");
                w.WriteLine(";");
            }

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags follow IBUF" + (mesh.GeometryStates.Count > 0 ? " and GeoStates" : ""));
                w.WriteLine("; (They are ignored on import.)");
                w.WriteLine(";");
            }

            VRTF vrtf      = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;

            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);

            //For backward compatibility, these come after the IBUFs
            Export_MeshGeoStates(w, vrtf, uvScales, mlod, mesh,
                                 GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF,
                                 GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF);

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags");
                w.WriteLine(";");
                w.WriteLine("flags " + mesh.Flags);
                w.Flush();
            }
        }
コード例 #7
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            VRTF vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;
            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);
        }
コード例 #8
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            if (mesh.GeometryStates.Count > 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: GeoStates follow IBUF");
                w.WriteLine(";");
            }

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags follow IBUF" + (mesh.GeometryStates.Count > 0 ? " and GeoStates" : ""));
                w.WriteLine("; (They are ignored on import.)");
                w.WriteLine(";");
            }

            VRTF vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;
            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);

            //For backward compatibility, these come after the IBUFs
            Export_MeshGeoStates(w, vrtf, uvScales, mlod, mesh,
                GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF,
                GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF);

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags");
                w.WriteLine(";");
                w.WriteLine("flags " + mesh.Flags);
                w.Flush();
            }
        }
コード例 #9
0
ファイル: Export.cs プロジェクト: yakoder/sims3tools
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            VRTF vrtf      = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;

            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);
        }
コード例 #10
0
        void Export_MeshGeoStates(StreamWriter w, VRTF vrtf, float[] uvScales, MLOD mlod, MLOD.Mesh mesh, VBUF vbuf, IBUF ibuf)
        {
            if (mesh.GeometryStates.Count <= 0)
            {
                return;
            }

            w.WriteLine(";");
            w.WriteLine("; Extended format: GeoStates");
            w.WriteLine(";");

            w.Export_GEOS(mpb, mesh);

            for (int g = 0; g < mesh.GeometryStates.Count; g++)
            {
                Export_VBUF_Geos(w, vbuf, vrtf, uvScales, mesh, g);
                Export_IBUF_Geos(w, ibuf, mesh, g);
            }

            w.Flush();
        }
コード例 #11
0
        //Match what Wes's compiler does
        public static void FixUVScales(this GenericRCOLResource rcolResource, MLOD.Mesh mesh)
        {
            MATD matd = GetMATDforMesh(rcolResource, mesh.MaterialIndex);
            if (matd == null)
                throw new ArgumentException("No MATD found for requested mesh");

            foreach (FieldType ft in new FieldType[] { FieldType.UVScales, FieldType.DiffuseUVSelector, FieldType.SpecularUVSelector, })
            {
                ShaderData data = (matd.Version < 0x0103 ? matd.Mtrl.SData : matd.Mtnf.SData).Find(x => x.Field == ft);
                if (data == null)
                    continue;

                if (!(data is ElementFloat3))
                    throw new InvalidOperationException(String.Format("Found " + ft + " of type '{0}'; expected 'ElementFloat3'.", data.GetType().Name));

                ElementFloat3 e = data as ElementFloat3;
                e.Data0 = 1f / short.MaxValue;
                e.Data1 = 0f;
                e.Data2 = 0f;
            }
        }
コード例 #12
0
 //find the chunk, replace the chunk, perhaps create or remove the reference
 public static void ReplaceChunk(this GenericRCOLResource rcolResource, MLOD.Mesh mesh, string field, IResourceKey rk, ARCOLBlock block)
 {
     ARCOLBlock current = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, (GenericRCOLResource.ChunkReference)mesh[field].Value) as ARCOLBlock;
     if (block != null)
     {
         if (current != null) // replacing is easy
         {
             if (current.Tag != block.Tag)
                 throw new Exception(string.Format("mesh field {0} is '{1}' but replacement is '{2}'.", field, current.Tag, block.Tag));
             // ...not entirely sure if these are required...
             current.Data = block.Data;
             block = current;
         }
         else // adding is okay
         {
             rcolResource.ChunkEntries.Add(new GenericRCOLResource.ChunkEntry(0, null, new TGIBlock(0, null, rk), block));
             mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), GenericRCOLResource.ChunkReference.CreateReference(rcolResource, rk), "X");
         }
     }
     else // deleting is not allowed - we can only null the reference, not remove the chunk
     {
         mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), new GenericRCOLResource.ChunkReference(0, null, 0), "X");
     }
 }
コード例 #13
0
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (String.IsNullOrEmpty(value as string))
            {
                return(null);
            }

            var path = value as string;

            if (path != null && File.Exists(path))
            {
                using (FileStream s = File.OpenRead(path))
                {
                    var  rcol = new GenericRCOLResource(0, s);
                    MLOD mlod = rcol.ChunkEntries
                                .Where(x => x.RCOLBlock is MLOD)
                                .Select(x => x.RCOLBlock)
                                .Cast <MLOD>()
                                .FirstOrDefault();


                    double minX = double.MaxValue, minZ = double.MaxValue, maxX = double.MinValue, maxZ = double.MinValue;


                    var pnty = new List <Point[]>();
                    foreach (MLOD.Mesh mesh in mlod.Meshes)
                    {
                        var vbuf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.VertexBufferIndex) as VBUF;
                        var ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.IndexBufferIndex) as IBUF;
                        var vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.VertexFormatIndex) as VRTF;
                        if (vrtf == null)
                        {
                            continue;
                        }
                        Vertex[] verts   = vbuf.GetVertices(mesh, vrtf, null);
                        int[]    indices = ibuf.GetIndices(mesh);
                        for (int i = 0; i < indices.Length / 3; i++)
                        {
                            var tst  = new int[3];
                            var poly = new Point[3];
                            for (int j = 0; j < 3; j++)
                            {
                                Vertex vert = verts[indices[i * 3 + j]];
                                double x    = (Offset + (vert.Position[0] * Scale));
                                double z    = -(Offset + (vert.Position[2] * Scale));
                                poly[j] = new Point((int)x, (int)z);
                                if (poly[j].X > maxX)
                                {
                                    maxX = poly[j].X;
                                }

                                if (poly[j].X < minX)
                                {
                                    minX = poly[j].X;
                                }

                                if (poly[j].Y > maxZ)
                                {
                                    maxZ = poly[j].Y;
                                }

                                if (poly[j].Y < minZ)
                                {
                                    minZ = poly[j].Y;
                                }
                            }
                            pnty.Add(poly);
                        }
                    }
                    var      width  = (int)(maxX - minX);
                    var      height = (int)(maxZ - minZ);
                    var      bmp    = new Bitmap(width, height);
                    Graphics gBmp   = Graphics.FromImage(bmp);
                    gBmp.CompositingMode = CompositingMode.SourceCopy;
                    float bright            = 1.1f;
                    System.Drawing.Color c  = System.Drawing.Color.FromArgb(255, Fill.R, Fill.G, Fill.B);
                    System.Drawing.Color c2 = System.Drawing.Color.FromArgb(255, Stroke.R, Stroke.G, Stroke.B);

                    var b = new SolidBrush(c);


                    var b2  = new SolidBrush(c2);
                    var pen = new Pen(b2);
                    foreach (Point[] pointse in pnty)
                    {
                        Point[] scaled = pointse.Select(old => new Point((int)(old.X - minX), (int)(old.Y - minZ))).ToArray();
                        gBmp.FillPolygon(b, scaled);
                    }
                    foreach (Point[] pointse in pnty)
                    {
                        Point[] scaled = pointse.Select(old => new Point((int)(old.X - minX), (int)(old.Y - minZ))).ToArray();
                        gBmp.DrawPolygon(pen, scaled);
                    }
                    var bmpImg = new BitmapImage();

                    var ms = new MemoryStream();

                    bmp.Save(ms, ImageFormat.Png);
                    ms.Position = 0L;
                    bmpImg.BeginInit();
                    bmpImg.StreamSource = ms;
                    bmpImg.EndInit();
                    return(bmpImg);
                }
            }
            return(null);
        }
コード例 #14
0
ファイル: Import.cs プロジェクト: yakoder/sims3tools
        //--


        public void Import_Mesh(StreamReader r, MLOD.Mesh mesh, GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, out meshExpImp.ModelBlocks.Vertex[] mverts)
        {
            #region Import VRTF
            bool isDefaultVRTF  = false;
            VRTF defaultForMesh = VRTF.CreateDefaultForMesh(mesh);

            VRTF vrtf = new VRTF(rcolResource.RequestedApiVersion, null)
            {
                Version = 2, Layouts = null,
            };
            r.Import_VRTF(mpb, vrtf);

            IResourceKey vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.VertexFormatIndex);
            if (vrtfRK == null)
            {
                vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (vrtfRK == null)
                {
                    vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.ScaleOffsetIndex);
                }
                if (vrtfRK == null)
                {
                    vrtfRK = new TGIBlock(0, null, 0, 0,
                                          System.Security.Cryptography.FNV64.GetHash(DateTime.UtcNow.ToString() + defaultRK.ToString()));
                }
                vrtfRK = new TGIBlock(0, null, vrtfRK)
                {
                    ResourceType = vrtf.ResourceType,
                };
            }

            if (vrtf.Equals(defaultForMesh))
            {
                isDefaultVRTF          = true;
                mesh.VertexFormatIndex = new GenericRCOLResource.ChunkReference(0, null, 0);//Clear the reference
            }
            else
            {
                rcolResource.ReplaceChunk(mesh, "VertexFormatIndex", vrtfRK, vrtf);
            }
            #endregion

            #region Import SKIN
            // we need to read the data in the file...
            SKIN skin = new SKIN(rcolResource.RequestedApiVersion, null)
            {
                Version = 1, Bones = null,
            };
            r.Import_SKIN(mpb, skin);

            // However, we do *NOT* want to update the RCOL with what we read - we are not replacing the object skeleton here
#if UNDEF
            if (skin.Bones != null)
            {
                IResourceKey skinRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (skinRK == null)
                {
                    skinRK = new TGIBlock(0, null, vrtfRK)
                    {
                        ResourceType = skin.ResourceType,
                    }
                }
                ;

                rcolResource.ReplaceChunk(mesh, "SkinControllerIndex", skinRK, skin);
            }
#endif
            #endregion

            mverts = Import_VBUF_Main(r, mlod, mesh, vrtf, isDefaultVRTF);

            #region Import IBUF
            IBUF ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF;
            if (ibuf == null)
            {
                ibuf = new IBUF(rcolResource.RequestedApiVersion, null)
                {
                    Version = 2, Flags = IBUF.FormatFlags.DifferencedIndices, DisplayListUsage = 0,
                }
            }
            ;
            Import_IBUF_Main(r, mlod, mesh, ibuf);

            IResourceKey ibufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.IndexBufferIndex);
            if (ibufRK == null)
            {
                ibufRK = new TGIBlock(0, null, defaultRK)
                {
                    ResourceType = ibuf.ResourceType,
                }
            }
            ;

            rcolResource.ReplaceChunk(mesh, "IndexBufferIndex", ibufRK, ibuf);
            #endregion

            #region Update the JointReferences
            UIntList joints = CreateJointReferences(mesh, mverts, skin);

            List <uint> added   = new List <uint>(joints);
            List <uint> removed = new List <uint>();
            foreach (var j in mesh.JointReferences)
            {
                if (joints.Contains(j))
                {
                    added.Remove(j);
                }
                else
                {
                    removed.Add(j);
                }
            }

            // Remove root
            removed.Remove(0xCD68F001);

            if (added.Count != 0)
            {
                mesh.JointReferences.AddRange(added);

                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with newly assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           added.Count,
                                                                           String.Join(", ", added.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }

            // with the 20120601 change to export, this warning on import has lost its severity... and been dropped.
#if UNDEF
            if (removed.Count != 0)
            {
//#if UNDEF
                // http://dino.drealm.info/den/denforum/index.php?topic=394.msg3876#msg3876
                removed.ForEach(j => mesh.JointReferences[mesh.JointReferences.IndexOf(j)] = 0);
//#endif
                // However, OM felt more comfortable if there was some indication something a little odd was going on.
                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with no assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           removed.Count,
                                                                           String.Join(", ", removed.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }
#endif
            #endregion
        }

        ModelBlocks.Vertex[] Import_VBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, bool isDefaultVRTF)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'vbuf'.");
            }
            if (split[0] != "vbuf")
            {
                throw new InvalidDataException("Expected line tag 'vbuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'vbuf' line has invalid count.");
            }

            //Wes's MilkShape plug-in sends back the first line in all subsequent lines of a dropShadow.
            return(r.Import_VBUF(mpb, count, vrtf, (mesh.Flags & MeshFlags.ShadowCaster) == 0));
        }

        void Import_IBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, IBUF ibuf)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'ibuf'.");
            }
            if (split[0] != "ibuf")
            {
                throw new InvalidDataException("Expected line tag 'ibuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'ibuf' line has invalid count.");
            }

            ibuf.SetIndices(mlod, mesh, r.Import_IBUF(mpb, IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType), count));
        }

        UIntList CreateJointReferences(MLOD.Mesh mesh, ModelBlocks.Vertex[] mverts, SKIN skin)
        {
            if (skin == null || skin.Bones == null)
            {
                return(new UIntList(null));
            }

            int maxReference = -1;

            foreach (var vert in mverts)
            {
                if (vert.BlendIndices != null)
                {
                    foreach (var reference in vert.BlendIndices)
                    {
                        if ((sbyte)reference > maxReference)
                        {
                            maxReference = reference;
                        }
                    }
                }
            }

            return(maxReference > -1 ? new UIntList(null, skin.Bones.GetRange(0, maxReference + 1).ConvertAll <uint>(x => x.NameHash)) : new UIntList(null));
        }
コード例 #15
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
        void Export_VBUF_Geos(StreamWriter w, VBUF vbuf, VRTF vrtf, float[] uvScales, MLOD.Mesh mesh, int geoStateIndex)
        {
            if (vbuf == null) { w.WriteLine("; vbuf is null for geoState"); w.WriteLine(string.Format("vbuf {0} 0 0", geoStateIndex)); return; }

            MLOD.GeometryState geoState = mesh.GeometryStates[geoStateIndex];

            if (geosVBUFIsContained(geoState, mesh)) w.WriteLine("; vbuf is contained within main mesh");
            w.WriteLine(string.Format("vbuf {0} {1} {2}", geoStateIndex, geoState.MinVertexIndex, geoState.VertexCount));
            if (geosVBUFIsContained(geoState, mesh)) return;

            w.Export_VBUF(mpb, vbuf.GetVertices(mesh, vrtf, geoState, uvScales), vrtf);
        }
コード例 #16
0
        public static void Import_GEOS(this StreamReader r, MyProgressBar mpb, MLOD.Mesh mesh)
        {
            if (r.EndOfStream)
            {
                mesh.GeometryStates = new MLOD.GeometryStateList(null);
                return;
            }

            string tagLine = r.ReadTag();
            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2 || split[0] != "geos")
                return;
            int count;
            if (!int.TryParse(split[1], out count))
                throw new InvalidDataException("'geos' line has invalid count.");

            mpb.Init("Import MeshGeoStates...", count);

            int sizePerPrimitive = IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType);
            int lastMinVertexIndex = mesh.MinVertexIndex;
            int lastVertexCount = 0;
            int lastStartIndex = mesh.PrimitiveCount * IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType);
            int lastPrimitiveCount = 0;
            for (int g = 0; g < count; g++)
            {
                split = r.ReadLine().Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
                if (split.Length != 2)
                    throw new InvalidDataException(string.Format("'geos' line {0} has invalid format.", g));
                int index;
                if (!int.TryParse(split[0], out index))
                    throw new InvalidDataException(string.Format("'geos' line {0} has invalid line index.", g));
                if (index != g)
                    throw new InvalidDataException(string.Format("'geos' line {0} has incorrect line index value {1}.", g, index));
                uint name;
                if (!uint.TryParse(split[1], System.Globalization.NumberStyles.HexNumber, null, out name))
                    throw new InvalidDataException(string.Format("'geos' line {0} has invalid name hash.", g));

                if (g < mesh.GeometryStates.Count)
                {
                    mesh.GeometryStates[g].Name = name;
                    lastMinVertexIndex = mesh.GeometryStates[g].MinVertexIndex;
                    lastVertexCount = mesh.GeometryStates[g].VertexCount;
                    lastStartIndex = mesh.GeometryStates[g].StartIndex;
                    lastPrimitiveCount = mesh.GeometryStates[g].PrimitiveCount;
                }
                else
                    mesh.GeometryStates.Add(new MLOD.GeometryState(0, null)
                    {
                        Name = name,
                        MinVertexIndex = lastMinVertexIndex + lastVertexCount,
                        VertexCount = 0,
                        StartIndex = lastStartIndex + lastPrimitiveCount * sizePerPrimitive,
                        PrimitiveCount = 0,
                    });

                mpb.Value = g;
            }
            mpb.Done();
        }
コード例 #17
0
        public static void Export_GEOS(this StreamWriter w, MyProgressBar mpb, MLOD.Mesh mesh)
        {
            w.WriteLine(string.Format("geos {0}", mesh.GeometryStates.Count));

            for (int g = 0; g < mesh.GeometryStates.Count; g++)
                w.WriteLine(string.Format("{0} {1:X8}", g, mesh.GeometryStates[g].Name));
        }
コード例 #18
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
 bool geosIBUFIsContained(MLOD.GeometryState geoState, int sizePerPrimitive, MLOD.Mesh mesh)
 {
     return geoState.StartIndex + geoState.PrimitiveCount * sizePerPrimitive <= mesh.StartIndex + mesh.PrimitiveCount * sizePerPrimitive;
 }
コード例 #19
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
        void Export_MeshGeoStates(StreamWriter w, VRTF vrtf, float[] uvScales, MLOD mlod, MLOD.Mesh mesh, VBUF vbuf, IBUF ibuf)
        {
            if (mesh.GeometryStates.Count <= 0) return;

            w.WriteLine(";");
            w.WriteLine("; Extended format: GeoStates");
            w.WriteLine(";");

            w.Export_GEOS(mpb, mesh);

            for (int g = 0; g < mesh.GeometryStates.Count; g++)
            {
                Export_VBUF_Geos(w, vbuf, vrtf, uvScales, mesh, g);
                Export_IBUF_Geos(w, ibuf, mesh, g);
            }

            w.Flush();
        }
コード例 #20
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
        private bool SetVertices(MLOD mlod, s3pi.GenericRCOLResource.GenericRCOLResource.ChunkReference myVBI, long beforeLength, int count, VRTF vrtf, IEnumerable<Vertex> vertices, float[] uvscales)
        {
            bool okay = true;
            byte[] before = new byte[beforeLength];
            Array.Copy(mBuffer, before, before.Length);

            long afterPos = Math.Min(mBuffer.Length, beforeLength + (count * vrtf.Stride));
            byte[] after = new byte[mBuffer.Length - afterPos];
            Array.Copy(mBuffer, afterPos, after, 0, after.Length);

            long offset = 0;
            using (MemoryStream mg = new MemoryStream())
            {
                if (!SetVertices(mg, vrtf, vertices, uvscales)) okay = false;
                offset = beforeLength + mg.Length - afterPos;

                mBuffer = new byte[before.Length + mg.Length + after.Length];
                Array.Copy(before, mBuffer, before.Length);
                Array.Copy(mg.ToArray(), 0, mBuffer, before.Length, mg.Length);
                Array.Copy(after, 0, mBuffer, before.Length + mg.Length, after.Length);

                mg.Close();
            }

            int voffset = (int)offset / vrtf.Stride;
            if (offset != 0)
                foreach (var m in mlod.Meshes.Where(m => m.VertexBufferIndex.Equals(myVBI) && m.StreamOffset > beforeLength))
                {
                    m.StreamOffset = (uint)(m.StreamOffset + offset);
                    foreach (var g in m.GeometryStates)
                        if (g.MinVertexIndex * vrtf.Stride > beforeLength)
                            g.MinVertexIndex += voffset;
                }
            return okay;
        }
コード例 #21
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, MLOD.Mesh mesh, int geoIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     return SetVertices(mlod, mesh, mesh.GeometryStates[geoIndex], vrtf, vertices, uvscales);
 }
コード例 #22
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, int meshIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     return SetVertices(mlod, mlod.Meshes[meshIndex], vrtf, vertices, uvscales);
 }
コード例 #23
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public Vertex[] GetVertices(MLOD.Mesh mesh, VRTF vrtf, float[] uvscales)
 {
     return GetVertices(vrtf, mesh.StreamOffset, mesh.VertexCount, uvscales);
 }
コード例 #24
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
 public Int32[] GetIndices(MLOD.Mesh mesh, int geoStateIndex)
 {
     return GetIndices(mesh, mesh.GeometryStates[geoStateIndex]);
 }
コード例 #25
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
 public Int32[] GetIndices(MLOD.Mesh mesh)
 {
     return GetIndices(mesh.PrimitiveType, mesh.StartIndex, mesh.PrimitiveCount);
 }
コード例 #26
0
ファイル: Import.cs プロジェクト: yakoder/sims3tools
        //--


        public void Import_Mesh(StreamReader r, MLOD.Mesh mesh, GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, out meshExpImp.ModelBlocks.Vertex[] mverts, out List <meshExpImp.ModelBlocks.Vertex[]> lverts)
        {
            #region Import VRTF
            bool isDefaultVRTF  = false;
            VRTF defaultForMesh = VRTF.CreateDefaultForMesh(mesh);

            VRTF vrtf = new VRTF(rcolResource.RequestedApiVersion, null)
            {
                Version = 2, Layouts = null,
            };
            r.Import_VRTF(mpb, vrtf);

            IResourceKey vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.VertexFormatIndex);
            if (vrtfRK == null)
            {
                vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (vrtfRK == null)
                {
                    vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.ScaleOffsetIndex);
                }
                if (vrtfRK == null)
                {
                    vrtfRK = new TGIBlock(0, null, 0, 0,
                                          System.Security.Cryptography.FNV64.GetHash(DateTime.UtcNow.ToString() + defaultRK.ToString()));
                }
                vrtfRK = new TGIBlock(0, null, vrtfRK)
                {
                    ResourceType = vrtf.ResourceType,
                };
            }

            if (vrtf.Equals(defaultForMesh))
            {
                isDefaultVRTF          = true;
                mesh.VertexFormatIndex = new GenericRCOLResource.ChunkReference(0, null, 0);//Clear the reference
            }
            else
            {
                rcolResource.ReplaceChunk(mesh, "VertexFormatIndex", vrtfRK, vrtf);
            }
            #endregion

            #region Import SKIN
            // we need to read the data in the file...
            SKIN skin = new SKIN(rcolResource.RequestedApiVersion, null)
            {
                Version = 1, Bones = null,
            };
            r.Import_SKIN(mpb, skin);

            // However, we do *NOT* want to update the RCOL with what we read - we are not replacing the object skeleton here
#if UNDEF
            if (skin.Bones != null)
            {
                IResourceKey skinRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (skinRK == null)
                {
                    skinRK = new TGIBlock(0, null, vrtfRK)
                    {
                        ResourceType = skin.ResourceType,
                    }
                }
                ;

                rcolResource.ReplaceChunk(mesh, "SkinControllerIndex", skinRK, skin);
            }
#endif
            #endregion

            mverts = Import_VBUF_Main(r, mlod, mesh, vrtf, isDefaultVRTF);

            #region Import IBUF
            IBUF ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF;
            if (ibuf == null)
            {
                ibuf = new IBUF(rcolResource.RequestedApiVersion, null)
                {
                    Version = 2, Flags = IBUF.FormatFlags.DifferencedIndices, DisplayListUsage = 0,
                }
            }
            ;
            Import_IBUF_Main(r, mlod, mesh, ibuf);

            IResourceKey ibufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.IndexBufferIndex);
            if (ibufRK == null)
            {
                ibufRK = new TGIBlock(0, null, defaultRK)
                {
                    ResourceType = ibuf.ResourceType,
                }
            }
            ;

            rcolResource.ReplaceChunk(mesh, "IndexBufferIndex", ibufRK, ibuf);
            #endregion

            // This reads both VBUF Vertex[]s and the ibufs; but the ibufs just go straight in quite happily
            lverts = Import_MeshGeoStates(r, mlod, mesh, vrtf, isDefaultVRTF, ibuf);

            #region Update the JointReferences
            UIntList joints = CreateJointReferences(mesh, mverts, lverts ?? new List <meshExpImp.ModelBlocks.Vertex[]>(), skin);

            List <uint> added   = new List <uint>(joints);
            List <uint> removed = new List <uint>();
            foreach (var j in mesh.JointReferences)
            {
                if (joints.Contains(j))
                {
                    added.Remove(j);
                }
                else
                {
                    removed.Add(j);
                }
            }

            // Remove root
            removed.Remove(0xCD68F001);

            if (added.Count != 0)
            {
                mesh.JointReferences.AddRange(added);

                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with newly assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           added.Count,
                                                                           String.Join(", ", added.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }

// with the 20120601 change to export, this warning on import has lost its severity... and been dropped.
#if UNDEF
            if (removed.Count != 0)
            {
//#if UNDEF
                // http://dino.drealm.info/den/denforum/index.php?topic=394.msg3876#msg3876
                removed.ForEach(j => mesh.JointReferences[mesh.JointReferences.IndexOf(j)] = 0);
//#endif
                // However, OM felt more comfortable if there was some indication something a little odd was going on.
                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with no assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           removed.Count,
                                                                           String.Join(", ", removed.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }
#endif
            #endregion
        }

        meshExpImp.ModelBlocks.Vertex[] Import_VBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, bool isDefaultVRTF)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'vbuf'.");
            }
            if (split[0] != "vbuf")
            {
                throw new InvalidDataException("Expected line tag 'vbuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'vbuf' line has invalid count.");
            }

            return(r.Import_VBUF(mpb, count, vrtf));
        }

        void Import_IBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, IBUF ibuf)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'ibuf'.");
            }
            if (split[0] != "ibuf")
            {
                throw new InvalidDataException("Expected line tag 'ibuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'ibuf' line has invalid count.");
            }

            ibuf.SetIndices(mlod, mesh, r.Import_IBUF(mpb, IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType), count));
        }

        List <meshExpImp.ModelBlocks.Vertex[]> Import_MeshGeoStates(StreamReader r, MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, bool isDefaultVRTF, IBUF ibuf)
        {
            MLOD.GeometryStateList oldGeos = new MLOD.GeometryStateList(null, mesh.GeometryStates);
            r.Import_GEOS(mpb, mesh);
            if (mesh.GeometryStates.Count <= 0)
            {
                return(null);
            }

            List <meshExpImp.ModelBlocks.Vertex[]> lverts = new List <meshExpImp.ModelBlocks.Vertex[]>();

            for (int g = 0; g < mesh.GeometryStates.Count; g++)
            {
                lverts.Add(Import_VBUF_Geos(r, mlod, mesh, g, vrtf, isDefaultVRTF));
                Import_IBUF_Geos(r, mlod, mesh, g, ibuf);
            }
            return(lverts);
        }

        UIntList CreateJointReferences(MLOD.Mesh mesh, meshExpImp.ModelBlocks.Vertex[] mverts, List <meshExpImp.ModelBlocks.Vertex[]> lverts, SKIN skin)
        {
            if (skin == null || skin.Bones == null)
            {
                return(new UIntList(null));
            }

            int maxReference = -1;

            lverts.Insert(0, mverts);
            foreach (var vertices in lverts)
            {
                if (vertices != null)
                {
                    foreach (var vert in vertices)
                    {
                        if (vert.BlendIndices != null)
                        {
                            foreach (var reference in vert.BlendIndices)
                            {
                                if ((sbyte)reference > maxReference)
                                {
                                    maxReference = reference;
                                }
                            }
                        }
                    }
                }
            }
            lverts.Remove(mverts);

            return(maxReference > -1 ? new UIntList(null, skin.Bones.GetRange(0, maxReference + 1).ConvertAll <uint>(x => x.NameHash)) : new UIntList(null));
        }

        meshExpImp.ModelBlocks.Vertex[] Import_VBUF_Geos(StreamReader r, MLOD mlod, MLOD.Mesh mesh, int geoStateIndex, VRTF vrtf, bool isDefaultVRTF)
        {
            //w.WriteLine(string.Format("vbuf {0} {1} {2}", geoStateIndex, mesh.GeometryStates[geoStateIndex].MinVertexIndex, mesh.GeometryStates[geoStateIndex].VertexCount));
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 4)
            {
                throw new InvalidDataException(string.Format("Invalid tag line read for geoState {0} 'vbuf'.", geoStateIndex));
            }
            if (split[0] != "vbuf")
            {
                throw new InvalidDataException("Expected line tag 'vbuf' not found.");
            }
            int lineIndex;

            if (!int.TryParse(split[1], out lineIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has invalid geoStateIndex.", geoStateIndex));
            }
            if (lineIndex != geoStateIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has incorrect geoStateIndex value {1}.", geoStateIndex, lineIndex));
            }
            int minVertexIndex;

            if (!int.TryParse(split[2], out minVertexIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has invalid MinVertexIndex.", geoStateIndex));
            }
            int vertexCount;

            if (!int.TryParse(split[3], out vertexCount))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has invalid VertexCount.", geoStateIndex));
            }

            if (minVertexIndex + vertexCount <= mesh.MinVertexIndex + mesh.VertexCount)
            {
                mesh.GeometryStates[geoStateIndex].MinVertexIndex = minVertexIndex;
                mesh.GeometryStates[geoStateIndex].VertexCount    = vertexCount;
                return(null);
            }

            if (minVertexIndex != mesh.GeometryStates[geoStateIndex].MinVertexIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has unexpected MinVertexIndex {1}; expected {2}.", geoStateIndex, minVertexIndex, mesh.GeometryStates[geoStateIndex].MinVertexIndex));
            }
            return(r.Import_VBUF(mpb, vertexCount, vrtf));
        }

        void Import_IBUF_Geos(StreamReader r, MLOD mlod, MLOD.Mesh mesh, int geoStateIndex, IBUF ibuf)
        {
            //w.WriteLine(string.Format("ibuf {0} {1} {2}", geoStateIndex, mesh.GeometryStates[geoStateIndex].StartIndex, mesh.GeometryStates[geoStateIndex].PrimitiveCount));
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 4)
            {
                throw new InvalidDataException("Invalid tag line read for 'ibuf'.");
            }
            if (split[0] != "ibuf")
            {
                throw new InvalidDataException("Expected line tag 'ibuf' not found.");
            }
            int lineIndex;

            if (!int.TryParse(split[1], out lineIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has invalid geoStateIndex.", geoStateIndex));
            }
            if (lineIndex != geoStateIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has incorrect geoStateIndex value {1}.", geoStateIndex, lineIndex));
            }
            int startIndex;

            if (!int.TryParse(split[2], out startIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has invalid StartIndex.", geoStateIndex));
            }
            int primitiveCount;

            if (!int.TryParse(split[3], out primitiveCount))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has invalid PrimitiveCount.", geoStateIndex));
            }

            int sizePerPrimitive = IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType);

            if (startIndex + primitiveCount * sizePerPrimitive <= mesh.StartIndex + mesh.PrimitiveCount * sizePerPrimitive)
            {
                mesh.GeometryStates[geoStateIndex].StartIndex     = startIndex;
                mesh.GeometryStates[geoStateIndex].PrimitiveCount = primitiveCount;
                return;
            }

            if (startIndex != mesh.GeometryStates[geoStateIndex].StartIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has unexpected StartIndex {1}; expected {2}.", geoStateIndex, startIndex, mesh.GeometryStates[geoStateIndex].StartIndex));
            }
            ibuf.SetIndices(mlod, mesh, geoStateIndex, r.Import_IBUF(mpb, IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType), primitiveCount));
        }
コード例 #27
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
 public Int32[] GetIndices(MLOD.Mesh mesh, MLOD.GeometryState geometryState)
 {
     return GetIndices(mesh.PrimitiveType, geometryState.StartIndex, geometryState.PrimitiveCount)
         .Select(x => x - geometryState.MinVertexIndex).ToArray();
 }
コード例 #28
0
ファイル: Export.cs プロジェクト: dd-dk/sims3tools
        void Export_IBUF_Geos(StreamWriter w, IBUF ibuf, MLOD.Mesh mesh, int geoStateIndex)
        {
            if (ibuf == null) { w.WriteLine("; ibuf is null for geoState"); w.WriteLine(string.Format("ibuf {0} 0 0", geoStateIndex)); return; }

            int sizePerPrimitive = IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType);
            MLOD.GeometryState geoState = mesh.GeometryStates[geoStateIndex];

            if (geosIBUFIsContained(geoState, sizePerPrimitive, mesh)) w.WriteLine("; ibuf is contained within main mesh");
            w.WriteLine(string.Format("ibuf {0} {1} {2}", geoStateIndex, geoState.StartIndex, geoState.PrimitiveCount));
            if (geosIBUFIsContained(geoState, sizePerPrimitive, mesh)) return;

            w.Export_IBUF(mpb, ibuf.GetIndices(mesh, geoStateIndex), sizePerPrimitive, geoState.PrimitiveCount);
        }
コード例 #29
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
        public BoundingBox GetBoundingBox(MLOD.Mesh mesh, VRTF vrtf)
        {
            BoundingBox bbox = null;

            GetBoundingBox(GetVertices(mesh, vrtf, null), ref bbox);
            foreach (var geos in mesh.GeometryStates)
                GetBoundingBox(GetVertices(mesh, vrtf, geos, null), ref bbox);

            return bbox ?? new BoundingBox(0, null);
        }
コード例 #30
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
 public void SetIndices(MLOD mlod, MLOD.Mesh mesh, Int32[] indices)
 {
     SetIndices(mlod, mesh.IndexBufferIndex, mesh.PrimitiveType, mesh.StartIndex, mesh.PrimitiveCount, indices);
     mesh.PrimitiveCount = indices.Length / IndexCountFromPrimitiveType(mesh.PrimitiveType);
 }
コード例 #31
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public Vertex[] GetVertices(MLOD.Mesh mesh, VRTF vrtf, MLOD.GeometryState geo, float[] uvscales)
 {
     return GetVertices(vrtf, mesh.StreamOffset + (geo.MinVertexIndex * vrtf.Stride), geo.VertexCount, uvscales);
 }
コード例 #32
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
 public void SetIndices(MLOD mlod, MLOD.Mesh mesh, int geoStateIndex, Int32[] indices)
 {
     MLOD.GeometryState geometryState = mesh.GeometryStates[geoStateIndex];
     SetIndices(mlod, mesh, geometryState, indices);
 }
コード例 #33
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     bool okay = SetVertices(mlod, mesh.VertexBufferIndex, mesh.StreamOffset, mesh.VertexCount, vrtf, vertices, uvscales);
     mesh.VertexCount = vertices.Length;
     return okay;
 }
コード例 #34
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
 public void SetIndices(MLOD mlod, MLOD.Mesh mesh, MLOD.GeometryState geometryState, Int32[] indices)
 {
     SetIndices(mlod, mesh.IndexBufferIndex, mesh.PrimitiveType, geometryState.StartIndex, geometryState.PrimitiveCount,
         indices.Select(x => x + geometryState.MinVertexIndex).ToArray());
     geometryState.PrimitiveCount = indices.Length / IndexCountFromPrimitiveType(mesh.PrimitiveType);
 }
コード例 #35
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, MLOD.Mesh mesh, MLOD.GeometryState geo, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     long beforeLength = mesh.StreamOffset + (geo.MinVertexIndex * vrtf.Stride);
     bool okay = SetVertices(mlod, mesh.VertexBufferIndex, beforeLength, geo.VertexCount, vrtf, vertices, uvscales);
     geo.VertexCount = vertices.Length;
     return okay;
 }
コード例 #36
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
 void SetIndices(MLOD mlod, s4pi.GenericRCOLResource.GenericRCOLResource.ChunkReference myIBI, ModelPrimitiveType type, Int32 startIndex, Int32 primCount, Int32[] indices)
 {
     SetIndices(mlod, myIBI, startIndex, startIndex + primCount * IndexCountFromPrimitiveType(type), indices);
 }
コード例 #37
0
ファイル: ExportForm.cs プロジェクト: yakoder/sims3tools
        private void Export_Shown(object sender, EventArgs e)
        {
            try
            {
                sfdExport.Title += " -- Test version " + typeof(ExportForm).Assembly.GetName().Version.ToString();
                DialogResult dr = sfdExport.ShowDialog();
                if (dr != DialogResult.OK)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                string folder   = Path.GetDirectoryName(sfdExport.FileName);
                string filebase = Path.GetFileNameWithoutExtension(sfdExport.FileName).Replace("_filebase", "");

                try
                {
                    using (FileStream fs = new FileStream(Path.Combine(folder, string.Format("{0}_filebase.s3asc", filebase)), FileMode.Create, FileAccess.Write))
                    {
                        fs.Close();
                    }

                    GenericRCOLResource rcolResource = new GenericRCOLResource(0, stream);
                    MLOD mlod = null;

                    if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01661233)//MODL
                    {
                        this.Text = "Export MODL...";
                        var lodRef = rcolResource.GetMLODChunkRefforMODL();
                        if (lodRef == null)
                        {
                            CopyableMessageBox.Show("MODL (0x01661233) with no MLOD (0x01D10F34).",
                                                    "Invalid MODL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                            Environment.ExitCode = 1;
                            return;
                        }


                        mlod = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, lodRef) as MLOD;
                    }
                    else if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01D10F34)//MLOD
                    {
                        this.Text = "Export MLOD...";

                        mlod = rcolResource.ChunkEntries[0].RCOLBlock as MLOD;
                    }
                    else
                    {
                        CopyableMessageBox.Show("RCOL resource must be MODL (0x01661233) or MLOD (0x01D10F34).",
                                                "Invalid RCOL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                        Environment.ExitCode = 1;
                        return;
                    }

                    Export export = new Export(new MyProgressBar(label1, pb));

                    for (int m = 0; m < mlod.Meshes.Count; m++)
                    {
                        string fnMesh = Path.Combine(folder, string.Format("{0}_group{1:D2}.s3ascg", filebase, m));

                        using (FileStream fsMesh = new FileStream(fnMesh, FileMode.Create, FileAccess.Write))
                        {
                            export.Export_MLOD(new StreamWriter(fsMesh), rcolResource, mlod, mlod.Meshes[m]);
                            fsMesh.Close();
                        }
                    }

                    Environment.ExitCode = 0;
                }
                catch (Exception ex)
                {
                    CopyableMessageBox.IssueException(ex, "Error processing " + Program.Filename);
                    throw ex;
                }
            }
            finally { this.Close(); }
        }
コード例 #38
0
ファイル: IBUF.cs プロジェクト: falerin/Sims4Tools
        void SetIndices(MLOD mlod, s4pi.GenericRCOLResource.GenericRCOLResource.ChunkReference myIBI, Int32 beforeLength, Int32 afterPos, Int32[] indices)
        {
            Int32[] before = new Int32[beforeLength];
            Array.Copy(mBuffer, 0, before, 0, before.Length);

            Int32[] after = new Int32[mBuffer.Length - afterPos];
            Array.Copy(mBuffer, afterPos, after, 0, after.Length);

            mBuffer = new Int32[before.Length + indices.Length + after.Length];
            Array.Copy(before, 0, mBuffer, 0, before.Length);
            Array.Copy(indices, 0, mBuffer, before.Length, indices.Length);
            Array.Copy(after, 0, mBuffer, before.Length + indices.Length, after.Length);

            int offset = beforeLength + indices.Length - afterPos;
            if (offset != 0)
                foreach (var m in mlod.Meshes.FindAll(m => m.IndexBufferIndex.Equals(myIBI)))
                    if (m.StartIndex > beforeLength)
                    {
                        m.StartIndex += offset;
                        foreach (var g in m.GeometryStates)
                            if (g.StartIndex > beforeLength)
                                g.StartIndex += offset;
                    }
        }
コード例 #39
0
ファイル: Import.cs プロジェクト: yakoder/sims3tools
        public List <offScale> VertsToVBUFs(GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, List <meshExpImp.ModelBlocks.Vertex[]> lmverts, List <List <meshExpImp.ModelBlocks.Vertex[]> > llverts, bool updateBBs, bool updateUVs)
        {
            // List of UV elements going off scale
            List <offScale> offScales = new List <offScale>();

            // Find everything for each mesh group
            Dictionary <GenericRCOLResource.ChunkReference, List <int> > meshGroups = new Dictionary <GenericRCOLResource.ChunkReference, List <int> >();
            Dictionary <int, VRTF>    meshVRTF     = new Dictionary <int, VRTF>();
            Dictionary <int, float[]> meshUVScales = new Dictionary <int, float[]>();

            for (int m = 0; m < mlod.Meshes.Count; m++)
            {
                if (meshGroups.ContainsKey(mlod.Meshes[m].MaterialIndex))
                {
                    meshGroups[mlod.Meshes[m].MaterialIndex].Add(m);
                }
                else
                {
                    meshGroups.Add(mlod.Meshes[m].MaterialIndex, new List <int> {
                        m
                    });
                }
                VRTF vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mlod.Meshes[m].VertexFormatIndex) as VRTF ?? VRTF.CreateDefaultForMesh(mlod.Meshes[m]);
                meshVRTF.Add(m, vrtf);

                if (updateUVs)
                {
                    rcolResource.FixUVScales(mlod.Meshes[m]);
                }
                meshUVScales.Add(m, rcolResource.GetUVScales(mlod.Meshes[m]));
            }

            // Update the VBUFs for each mesh group and set the mesh bounds whilst we're here
            foreach (var key in meshGroups.Keys)
            {
                foreach (int m in meshGroups[key])
                {
                    VBUF vbuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mlod.Meshes[m].VertexBufferIndex) as VBUF;
                    if (vbuf == null)
                    {
                        vbuf = new VBUF(rcolResource.RequestedApiVersion, null)
                        {
                            Version = 0x00000101, Flags = VBUF.FormatFlags.None, SwizzleInfo = new GenericRCOLResource.ChunkReference(0, null, 0),
                        }
                    }
                    ;

                    offScales.AddRange(getOffScales(m, -1, lmverts[m], meshUVScales[m]));
                    vbuf.SetVertices(mlod, m, meshVRTF[m], lmverts[m], meshUVScales[m]);

                    if (llverts[m] != null)
                    {
                        for (int g = 0; g < llverts[m].Count; g++)
                        {
                            if (llverts[m][g] != null)
                            {
                                offScales.AddRange(getOffScales(m, g, llverts[m][g], meshUVScales[m]));
                                vbuf.SetVertices(mlod, mlod.Meshes[m], g, meshVRTF[m], llverts[m][g], meshUVScales[m]);
                            }
                        }
                    }

                    IResourceKey vbufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mlod.Meshes[m].VertexBufferIndex);
                    if (vbufRK == null)//means we created the VBUF: create a RK and add it
                    {
                        vbufRK = new TGIBlock(0, null, defaultRK)
                        {
                            ResourceType = vbuf.ResourceType,
                        }
                    }
                    ;

                    rcolResource.ReplaceChunk(mlod.Meshes[m], "VertexBufferIndex", vbufRK, vbuf);

                    if (updateBBs)
                    {
                        mlod.Meshes[m].Bounds = vbuf.GetBoundingBox(mlod.Meshes[m], meshVRTF[m]);
                    }
                }
            }

            return(offScales);
        }
コード例 #40
0
ファイル: ImportForm.cs プロジェクト: yakoder/sims3tools
        private void Import_Shown(object sender, EventArgs e)
        {
            try
            {
                ofdImport.Title += " -- Test version " + typeof(ImportForm).Assembly.GetName().Version.ToString();
                DialogResult dr = ofdImport.ShowDialog();
                if (dr != DialogResult.OK)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                string folder   = Path.GetDirectoryName(ofdImport.FileName);
                string filebase = Path.GetFileNameWithoutExtension(ofdImport.FileName).Replace("_filebase", "");

                if (!File.Exists(Path.Combine(folder, string.Format("{0}_filebase.s3m2b", filebase))))
                {
                    CopyableMessageBox.Show("File name must end \"_filebase.s3m2b\"",
                                            "Base file not found", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                    Environment.ExitCode = 1;
                    return;
                }

                bool updateBBs = false;
                int  q         = CopyableMessageBox.Show("Update mesh bounding boxes?", Application.ProductName, CopyableMessageBoxButtons.YesNoCancel, CopyableMessageBoxIcon.Question);
                if (q == 0)
                {
                    updateBBs = true;
                }
                else if (q == 2)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                bool updateUVs = false;
                q = CopyableMessageBox.Show("Maximise mapping area?", Application.ProductName, CopyableMessageBoxButtons.YesNoCancel, CopyableMessageBoxIcon.Question);
                if (q == 0)
                {
                    updateUVs = true;
                }
                else if (q == 2)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                try
                {
                    GenericRCOLResource rcolResource = new GenericRCOLResource(0, stream);
                    MLOD         mlod = null;
                    IResourceKey rk   = null;

                    if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01661233)//MODL
                    {
                        this.Text = "Import MODL...";
                        var lodRef = rcolResource.GetMLODChunkRefforMODL();
                        if (lodRef == null)
                        {
                            CopyableMessageBox.Show("MODL (0x01661233) with no MLOD (0x01D10F34).",
                                                    "Invalid MODL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                            Environment.ExitCode = 1;
                            return;
                        }

                        rk   = GenericRCOLResource.ChunkReference.GetKey(rcolResource, lodRef);
                        mlod = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, lodRef) as MLOD;
                    }
                    else if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01D10F34)//MLOD
                    {
                        this.Text = "Import MLOD...";
                        rk        = rcolResource.ChunkEntries[0].TGIBlock;
                        mlod      = rcolResource.ChunkEntries[0].RCOLBlock as MLOD;
                    }
                    else
                    {
                        CopyableMessageBox.Show("RCOL resource must be MODL (0x01661233) or MLOD (0x01D10F34).",
                                                "Invalid RCOL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                        Environment.ExitCode = 1;
                        return;
                    }

                    Import import = new Import(new MyProgressBar(label1, pb));

                    int m = 0;
                    List <meshExpImp.ModelBlocks.Vertex[]>         lmverts = new List <meshExpImp.ModelBlocks.Vertex[]>();
                    List <List <meshExpImp.ModelBlocks.Vertex[]> > llverts = new List <List <meshExpImp.ModelBlocks.Vertex[]> >();
                    while (true)
                    {
                        string fnMesh = Path.Combine(folder, string.Format("{0}_group{1:D2}.s3m2bg", filebase, m));
                        if (!File.Exists(fnMesh))
                        {
                            break;
                        }

                        using (FileStream fsMesh = new FileStream(fnMesh, FileMode.Open, FileAccess.Read))
                        {
                            meshExpImp.ModelBlocks.Vertex[]        mverts;
                            List <meshExpImp.ModelBlocks.Vertex[]> lverts;
                            import.Import_Mesh(new StreamReader(fsMesh), mlod.Meshes[m++], rcolResource, mlod, rk, out mverts, out lverts);
                            lmverts.Add(mverts);
                            llverts.Add(lverts);
                            fsMesh.Close();
                        }
                    }

                    List <Import.offScale> offScales = import.VertsToVBUFs(rcolResource, mlod, rk, lmverts, llverts, updateBBs, updateUVs);
                    if (offScales.Count > 0)
                    {
                        while (true)
                        {
                            switch (
                                CopyableMessageBox.Show(
                                    Application.ProductName + " has detected some off-scale UV mappings.\n" +
                                    "This may mean your mapping is not stored as you intended.\n" +
                                    "This is often caused by UV-mapping too close to the edge of the map.\n\n" +
                                    "Click 'Commit' to commit the change or 'Cancel' to abandon.",
                                    Application.ProductName, CopyableMessageBoxIcon.Warning, new String[] { "C&ommit", "&View", "C&ancel", }, 0, 2))
                            {
                            case 0:     //commit
                                goto Commit;

                            case 1:     //view
                                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                                offScales.ForEach(x => sb.AppendLine(x.ToString()));
                                CopyableMessageBox.Show(sb.ToString(),
                                                        Application.ProductName, CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Information);
                                break;

                            default:     //cancel
                                Environment.ExitCode = 1;
                                return;
                            }
                        }
                    }

Commit:
                    result = (byte[])rcolResource.AsBytes.Clone();

                    Environment.ExitCode = 0;
                }
                catch (Exception ex)
                {
                    CopyableMessageBox.IssueException(ex, "Error processing " + Program.Filename);
                    throw ex;
                }
            }
            finally { this.Close(); }
        }