Esempio n. 1
0
        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);
        }
        public static void Export_VRTF(this StreamWriter w, MyProgressBar mpb, VRTF vrtf)
        {
            w.WriteLine(string.Format("vrtf {0} {1}", vrtf.Layouts.Count, vrtf.Stride));

            mpb.Init("Export VRTF...", vrtf.Layouts.Count);
            for (int i = 0; i < vrtf.Layouts.Count; i++)
            {
                var l = vrtf.Layouts[i];
                w.WriteLine(string.Format("{0} {1} {2} {3} {4}", i, (byte)l.Usage, l.UsageIndex, (byte)l.Format, l.Offset));
                mpb.Value++;
            }
            w.Flush();
            mpb.Done();
        }
Esempio n. 3
0
File: VBUF.cs Progetto: 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;
        }
Esempio n. 4
0
File: VBUF.cs Progetto: 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);
 }
Esempio n. 5
0
File: VBUF.cs Progetto: 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);
 }
Esempio n. 6
0
File: VBUF.cs Progetto: dd-dk/s3pi
        public static void ReadUVData(byte[] data, VRTF.ElementLayout layout, ref float[] output, float scale)
        {
            byte[] element = new byte[VRTF.ByteSizeFromFormat(layout.Format)];
            Array.Copy(data, layout.Offset, element, 0, element.Length);

            switch (layout.Format)
            {
                case VRTF.ElementFormat.Short2:
                    for (int i = 0; i < output.Length; i++)
                    {
                        output[i] += (float)BitConverter.ToInt16(element, i * sizeof(short)) * scale;
                    }
                    break;
                case VRTF.ElementFormat.Short4:
                    for (int i = 0; i < output.Length; i++)
                        output[i] += (float)BitConverter.ToInt16(element, i * sizeof(short)) / short.MaxValue;
                    break;
                case VRTF.ElementFormat.Short4_DropShadow:
                    for (int i = 0; i < output.Length - 1; i++)
                        output[i] += (float)BitConverter.ToInt16(element, i * sizeof(short)) / short.MaxValue;
                    output[output.Length - 1] += (float)BitConverter.ToInt16(element, (output.Length - 1) * sizeof(short)) / 511;
                    break;
                default:
                    ReadFloatData(data, layout, ref output);
                    break;
            }
        }
Esempio n. 7
0
File: VBUF.cs Progetto: 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);
 }
Esempio n. 8
0
File: VBUF.cs Progetto: 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);
        }
Esempio n. 9
0
        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;
        }
        public static void Export_VBUF(this StreamWriter w, MyProgressBar mpb, meshExpImp.ModelBlocks.Vertex[] av, VRTF vrtf)
        {
            mpb.Init("Export VBUF...", av.Length);
            for (int i = 0; i < av.Length; i++)
            {
                meshExpImp.ModelBlocks.Vertex v = av[i];
                int nUV = 0;
                foreach (var layout in vrtf.Layouts)
                {
                    w.Write(string.Format("{0} {1}", i, (byte)layout.Usage));
                    switch (layout.Usage)
                    {
                    case VRTF.ElementUsage.Position:
                        if (v.Position != null)
                        {
                            foreach (float f in v.Position)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Position is null.");
                        }
                        break;

                    case VRTF.ElementUsage.Normal:
                        if (v.Normal != null)
                        {
                            foreach (float f in v.Normal)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Normal is null.");
                        }
                        break;

                    case VRTF.ElementUsage.UV:
                        if (v.UV != null)
                        {
                            foreach (float f in v.UV[nUV])
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(string.Format(" UV[{0}] is null.", nUV));
                        }
                        nUV++;
                        break;

                    case VRTF.ElementUsage.BlendIndex:
                        if (v.BlendIndices != null)
                        {
                            foreach (byte b in v.BlendIndices)
                            {
                                w.Write(string.Format(" {0}", b));
                            }
                        }
                        else
                        {
                            w.Write(" BlendIndices is null.");
                        }
                        break;

                    case VRTF.ElementUsage.BlendWeight:
                        if (v.BlendWeights != null)
                        {
                            foreach (float f in v.BlendWeights)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" BlendWeight is null.");
                        }
                        break;

                    case VRTF.ElementUsage.Tangent:
                        if (v.Tangents != null)
                        {
                            foreach (float f in v.Tangents)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Tangents is null.");
                        }
                        break;

                    case VRTF.ElementUsage.Colour:
                        if (v.Color != null)
                        {
                            foreach (float f in v.Color)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Colour is null.");
                        }
                        break;
                    }
                    w.WriteLine();
                    mpb.Value++;
                }
            }

            w.Flush();
            mpb.Done();
        }
Esempio n. 11
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();
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        //--


        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
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
File: VBUF.cs Progetto: dd-dk/s3pi
        private static bool SetVertices(MemoryStream s, VRTF vrtf, IEnumerable<Vertex> vertices, float[] uvscales)
        {
            bool okay = true;
            PositionMinMax(vrtf, vertices);

            byte[] output = new byte[vrtf.Stride];
            var position = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Position);
            var normal = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Normal);
            var uv = vrtf.Layouts
                .Where(x => x.Usage == VRTF.ElementUsage.UV)
                .ToArray();
            var blendIndices = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendIndex);
            var blendWeights = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendWeight);
            var tangents = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Tangent);
            var color = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Colour);
            if (uvscales == null) uvscales = defaultUVScales;
            foreach (var v in vertices)
            {
                if (v.Position != null) WritePositionData(v.Position, position, output, positionMax);
                if (v.Normal != null) WriteFloatData(v.Normal, normal, output);
                for (int u = 0; u < uv.Length; u++)
                {
                    var scale = u < uvscales.Length && uvscales[u] != 0 ? uvscales[u] : uvscales[0];
                    if (v.UV[u] != null)
                        if (!WriteUVData(v.UV[u], uv[u], output, scale))
                            okay = false;
                }
                if (v.BlendIndices != null) Array.Copy(v.BlendIndices, 0, output, blendIndices.Offset, VRTF.ByteSizeFromFormat(blendIndices.Format));
                if (v.BlendWeights != null) WriteFloatData(v.BlendWeights, blendWeights, output);
                if (v.Tangents != null) WriteFloatData(v.Tangents, tangents, output);
                if (v.Color != null) WriteFloatData(v.Color, color, output);
                s.Write(output, 0, output.Length);
            }
            s.Flush();
            return okay;
        }
Esempio n. 17
0
File: VBUF.cs Progetto: dd-dk/s3pi
        private static bool WriteUVData(float[] input, VRTF.ElementLayout layout, byte[] output, float scale)
        {
            bool okay = true;
            switch (layout.Format)
            {
                case VRTF.ElementFormat.Short2:
                    for (int i = 0; i < input.Length; i++)
                    {
                        if ((short)Math.Round(input[i] / scale) != (long)Math.Round(input[i] / scale)) okay = false;
                        Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] / scale)), 0, output, layout.Offset + i * sizeof(short), sizeof(short));
                    }
                    break;

                case VRTF.ElementFormat.Short4:
                    for (int i = 0; i < input.Length; i++)
                        Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * short.MaxValue)), 0, output, layout.Offset + i * sizeof(short), sizeof(short));
                    break;
                case VRTF.ElementFormat.Short4_DropShadow:
                    for (int i = 0; i < input.Length - 1; i++)
                        Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * short.MaxValue)), 0, output, layout.Offset + i * sizeof(short), sizeof(short));
                    Array.Copy(BitConverter.GetBytes((short)Math.Round(input[input.Length - 1] * 511)), 0, output, layout.Offset + (input.Length - 1) * sizeof(short), sizeof(short));
                    break;
                default:
                    WriteFloatData(input, layout, output);
                    break;
            }
            return okay;
        }
        public static void Import_VRTF(this StreamReader r, MyProgressBar mpb, VRTF vrtf)
        {
            string tagLine = r.ReadTag();

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

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

            if (!int.TryParse(split[2], out stride))
            {
                throw new InvalidDataException("'vrtf' line has invalid stride.");
            }

            if (count == 0)
            {
                return;
            }
            vrtf.Layouts = new VRTF.VertexElementLayoutList(null);

            vrtf.Stride = stride;

            mpb.Init("Import VRTF...", count);
            for (int l = 0; l < count; l++)
            {
                split = r.ReadLine().Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
                if (split.Length != 5)
                {
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has invalid format.", l));
                }
                int index;
                if (!int.TryParse(split[0], out index))
                {
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has invalid line index.", l));
                }
                if (index != l)
                {
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has incorrect line index value {1}.", l, index));
                }
                byte[] values = split.ConvertAll <byte>(1);
                if (values.Length != 4)
                {
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has incorrect number of byte values {1}.", l, values.Length));
                }

                vrtf.Layouts.Add(new VRTF.ElementLayout(0, null, (VRTF.ElementFormat)values[2], values[3], (VRTF.ElementUsage)values[0], values[1]));
                mpb.Value++;
            }
            mpb.Done();
        }
Esempio n. 19
0
        private void InitScene()
        {
            GeostatesPanel.Visibility = Visibility.Collapsed;
            GenericRCOLResource.ChunkEntry chunk = rcol.ChunkEntries.FirstOrDefault(x => x.RCOLBlock is MLOD);

            int polyCount = 0;
            int vertCount = 0;


            if (chunk != null)
            {
                var mlod = chunk.RCOLBlock as MLOD;
                foreach (MLOD.Mesh m in mlod.Meshes)
                {
                    try
                    {
                        vertCount += m.VertexCount;
                        polyCount += m.PrimitiveCount;
                        var        vbuf     = (VBUF)GenericRCOLResource.ChunkReference.GetBlock(rcol, m.VertexBufferIndex);
                        var        ibuf     = (IBUF)GenericRCOLResource.ChunkReference.GetBlock(rcol, m.IndexBufferIndex);
                        VRTF       vrtf     = (VRTF)GenericRCOLResource.ChunkReference.GetBlock(rcol, m.VertexFormatIndex) ?? VRTF.CreateDefaultForMesh(m);
                        IRCOLBlock material = GenericRCOLResource.ChunkReference.GetBlock(rcol, m.MaterialIndex);

                        MATD matd = FindMainMATD(rcol, material);

                        float[] uvscale = GetUvScales(matd);
                        if (uvscale != null)
                        {
                            Debug.WriteLine(string.Format("{0} - {1} - {2}", uvscale[0], uvscale[2], uvscale[2]));
                        }
                        else
                        {
                            Debug.WriteLine("No scales");
                        }

                        GeometryModel3D model = DrawModel(vbuf.GetVertices(m, vrtf, uvscale), ibuf.GetIndices(m), mNonSelectedMaterial);

                        var sceneMesh = new SceneMlodMesh(m, model);
                        if (matd != null)
                        {
                            sceneMesh.Shader = matd.Shader;
                            switch (matd.Shader)
                            {
                            case ShaderType.ShadowMap:
                            case ShaderType.DropShadow:
                                break;

                            default:
                                var maskWidth  = GetMATDParam <ElementInt>(matd, FieldType.MaskWidth);
                                var maskHeight = GetMATDParam <ElementInt>(matd, FieldType.MaskHeight);
                                if (maskWidth != null && maskHeight != null)
                                {
                                    float scalar = Math.Max(maskWidth.Data, maskHeight.Data);
                                    mCheckerBrush.Transform = new ScaleTransform(maskHeight.Data / scalar, maskWidth.Data / scalar);
                                }
                                break;
                            }
                        }
                        try
                        {
                            var sceneGeostates = new SceneGeostate[m.GeometryStates.Count];
                            for (int i = 0; i < sceneGeostates.Length; i++)
                            {
                                GeometryModel3D state = DrawModel(vbuf.GetVertices(m, vrtf, m.GeometryStates[i], uvscale),
                                                                  ibuf.GetIndices(m, m.GeometryStates[i]), mHiddenMaterial);
                                mGroupMeshes.Children.Add(state);
                                sceneGeostates[i] = new SceneGeostate(sceneMesh, m.GeometryStates[i], state);
                            }
                            sceneMesh.States = sceneGeostates;
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Unable to load Geostates.  You may have some corrupted data: " + ex.ToString(),
                                            "Unable to load Geostates...");
                        }
                        mGroupMeshes.Children.Add(model);
                        mSceneMeshes.Add(sceneMesh);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(String.Format("Unable to load mesh id 0x{0:X8}", m.Name));
                    }
                }
            }
            else
            {
                GenericRCOLResource.ChunkEntry geomChunk = rcol.ChunkEntries.FirstOrDefault();
                var geom  = new GEOM(0, null, geomChunk.RCOLBlock.Stream);
                var verts = new List <Vertex>();
                polyCount = geom.Faces.Count;
                vertCount = geom.VertexData.Count;
                foreach (GEOM.VertexDataElement vd in geom.VertexData)
                {
                    var v = new Vertex();

                    var pos = (GEOM.PositionElement)vd.Vertex.FirstOrDefault(e => e is GEOM.PositionElement);
                    if (pos != null)
                    {
                        v.Position = new[] { pos.X, pos.Y, pos.Z };
                    }


                    var norm = (GEOM.NormalElement)vd.Vertex.FirstOrDefault(e => e is GEOM.NormalElement);
                    if (norm != null)
                    {
                        v.Normal = new[] { norm.X, norm.Y, norm.Z };
                    }


                    var uv = (GEOM.UVElement)vd.Vertex.FirstOrDefault(e => e is GEOM.UVElement);
                    if (uv != null)
                    {
                        v.UV = new[] { new[] { uv.U, uv.V } };
                    }
                    verts.Add(v);
                }
                var facepoints = new List <int>();
                foreach (GEOM.Face face in geom.Faces)
                {
                    facepoints.Add(face.VertexDataIndex0);
                    facepoints.Add(face.VertexDataIndex1);
                    facepoints.Add(face.VertexDataIndex2);
                }

                GeometryModel3D model     = DrawModel(verts.ToArray(), facepoints.ToArray(), mNonSelectedMaterial);
                var             sceneMesh = new SceneGeomMesh(geom, model);
                mGroupMeshes.Children.Add(model);
                mSceneMeshes.Add(sceneMesh);
            }
            foreach (SceneMesh s in mSceneMeshes)
            {
                mMeshListView.Items.Add(s);
            }
            if (mSceneMeshes.Count <= 1)
            {
                MeshesPanel.Visibility = Visibility.Collapsed;
            }
            VertexCount.Text  = String.Format("Vertices: {0}", vertCount);
            PolygonCount.Text = String.Format("Polygons: {0}", polyCount);
        }
        public static meshExpImp.ModelBlocks.Vertex[] Import_VBUF(this StreamReader r, MyProgressBar mpb, int count, VRTF vrtf, bool milkShapeFix)
        {
            meshExpImp.ModelBlocks.Vertex[] vertices = new meshExpImp.ModelBlocks.Vertex[count];
            int uvLength = vrtf.Layouts.FindAll(x => x.Usage == VRTF.ElementUsage.UV).Count;

            int line = 0;

            mpb.Init("Import VBUF...", count);
            for (int v = 0; v < count; v++)
            {
                meshExpImp.ModelBlocks.Vertex vertex = new meshExpImp.ModelBlocks.Vertex();
                int nUV = 0;
                vertex.UV = new float[uvLength][];

                foreach (var layout in vrtf.Layouts)
                {
                    string[] split = r.ReadLine().Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
                    if (split.Length < 2)
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid format.", line));
                    }
                    int index;
                    if (!int.TryParse(split[0], out index))
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid line index.", line));
                    }
                    if (index != v)
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line index value {1}.", line, index));
                    }
                    byte usage;
                    if (!byte.TryParse(split[1], out usage))
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid line index.", v));
                    }
                    if (usage != (byte)layout.Usage)
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line Usage value {1}.", line, usage));
                    }

                    switch (usage)
                    {
                    case (byte)VRTF.ElementUsage.Position:
                        vertex.Position = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.Normal:
                        vertex.Normal = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.UV:
                        vertex.UV[nUV++] = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        //Wes's MilkShape plug-in sends back the first line in all subsequent lines of a dropShadow.
                        //Usually the values should be zero, so zero them. Program.UseFormat == Program.Format.s3asc &&
                        if (nUV > 1 && milkShapeFix)
                        {
                            for (int u = 0; u < vertex.UV[nUV - 1].Length; u++)
                            {
                                vertex.UV[nUV - 1][u] = 0f;
                            }
                        }
                        break;

                    case (byte)VRTF.ElementUsage.BlendIndex:
                        byte[] BlendIndices = split.ConvertAll <byte>(2);
                        if (!(BlendIndices.Length == VRTF.ByteSizeFromFormat(layout.Format) || BlendIndices.Length + 1 == VRTF.ByteSizeFromFormat(layout.Format)))
                        {
                            throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect format.", line));
                        }
                        vertex.BlendIndices = BlendIndices;
                        break;

                    case (byte)VRTF.ElementUsage.BlendWeight:
                        vertex.BlendWeights = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.Tangent:
                        vertex.Tangents = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.Colour:
                        vertex.Color = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;
                    }
                    line++;
                }
                vertices[v] = vertex;
                if (nUV != uvLength)
                {
                    throw new InvalidDataException(string.Format("'vbuf' vertex {0} read {1} UV lines, expected {2}.", v, nUV, uvLength));
                }
                mpb.Value++;
            }
            mpb.Done();

            return(vertices);
        }
Esempio n. 21
0
File: VBUF.cs Progetto: dd-dk/s3pi
 public Vertex[] GetVertices(MLOD.Mesh mesh, VRTF vrtf, float[] uvscales)
 {
     return GetVertices(vrtf, mesh.StreamOffset, mesh.VertexCount, uvscales);
 }
 static float[] GetFloats(VRTF.ElementFormat format, int line, float[] source)
 {
     float[] res = new float[VRTF.FloatCountFromFormat(format)];
     Array.Copy(source, res, Math.Min(source.Length, res.Length));
     return(res);
 }
Esempio n. 23
0
File: VBUF.cs Progetto: dd-dk/s3pi
        public Vertex[] GetVertices(VRTF vrtf, long offset, int count, float[] uvscales)
        {
            long streamOffset = offset;
            Stream s = new MemoryStream(mBuffer);
            s.Seek(streamOffset, SeekOrigin.Begin);

            var position = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Position);
            var normal = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Normal);
            var uv = vrtf.Layouts
                .Where(x => x.Usage == VRTF.ElementUsage.UV)
                .ToArray();
            var blendIndices = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendIndex);
            var blendWeights = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendWeight);
            var tangents = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Tangent);
            var color = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Colour);

            Vertex[] verts = new Vertex[count];
            if (uvscales == null) uvscales = new float[3];
            for (int i = 0; i < count; i++)
            {
                Vertex v = new Vertex();
                byte[] data = new byte[vrtf.Stride];
                s.Read(data, 0, vrtf.Stride);
                if (position != null)
                {
                    float[] posPoints = new float[VRTF.FloatCountFromFormat(position.Format)];
                    ReadFloatData(data, position, ref posPoints);
                    v.Position = posPoints;
                }
                if (normal != null)
                {
                    float[] normPoints = new float[VRTF.FloatCountFromFormat(normal.Format)];
                    ReadFloatData(data, normal, ref normPoints);
                    v.Normal = normPoints;
                }
                v.UV = new float[uv.Length][];
                for (int j = 0; j < uv.Length; j++)
                {
                    var u = uv[j];
                    float[] uvPoints = new float[VRTF.FloatCountFromFormat(u.Format)];
                    var scale = j < uvscales.Length && uvscales[j] != 0 ? uvscales[j] : uvscales[0];
                    ReadUVData(data, u, ref uvPoints, scale);
                    v.UV[j] = uvPoints;
                }
                if (blendIndices != null)
                {
                    byte[] blendIPoints = new byte[VRTF.ByteSizeFromFormat(blendIndices.Format)];
                    Array.Copy(data, blendIndices.Offset, blendIPoints, 0, blendIPoints.Length);
                    v.BlendIndices = blendIPoints;
                }
                if (blendWeights != null)
                {
                    float[] blendWPoints = new float[VRTF.FloatCountFromFormat(blendWeights.Format)];
                    ReadFloatData(data, blendWeights, ref blendWPoints);
                    v.BlendWeights = blendWPoints;
                }
                if (tangents != null)
                {
                    float[] tangentPoints = new float[VRTF.FloatCountFromFormat(tangents.Format)];
                    ReadFloatData(data, tangents, ref tangentPoints);
                    v.Tangents = tangentPoints;
                }
                if (color != null)
                {
                    float[] colorPoints = new float[VRTF.FloatCountFromFormat(color.Format)];
                    ReadFloatData(data, color, ref colorPoints);
                    v.Color = colorPoints;
                }
                verts[i] = v;
            }
            return verts;
        }
Esempio n. 24
0
        public static void Export_VBUF(this StreamWriter w, MyProgressBar mpb, meshExpImp.ModelBlocks.Vertex[] av, VRTF vrtf)
        {
            mpb.Init("Export VBUF...", av.Length);
            for (int i = 0; i < av.Length; i++)
            {
                meshExpImp.ModelBlocks.Vertex v = av[i];
                int nUV = 0;
                foreach (var layout in vrtf.Layouts)
                {
                    w.Write(string.Format("{0} {1}", i, (byte)layout.Usage));
                    switch (layout.Usage)
                    {
                        case VRTF.ElementUsage.Position:
                            if (v.Position != null) foreach (float f in v.Position) w.Write(string.Format(" {0:F6}", f));
                            else w.Write(" Position is null.");
                            break;
                        case VRTF.ElementUsage.Normal:
                            if (v.Normal != null) foreach (float f in v.Normal) w.Write(string.Format(" {0:F6}", f));
                            else w.Write(" Normal is null.");
                            break;
                        case VRTF.ElementUsage.UV:
                            if (v.UV != null) foreach (float f in v.UV[nUV]) w.Write(string.Format(" {0:F6}", f));
                            else w.Write(string.Format(" UV[{0}] is null.", nUV));
                            nUV++;
                            break;
                        case VRTF.ElementUsage.BlendIndex:
                            if (v.BlendIndices != null) foreach (byte b in v.BlendIndices) w.Write(string.Format(" {0}", b));
                            else w.Write(" BlendIndices is null.");
                            break;
                        case VRTF.ElementUsage.BlendWeight:
                            if (v.BlendWeights != null) foreach (float f in v.BlendWeights) w.Write(string.Format(" {0:F6}", f));
                            else w.Write(" BlendWeight is null.");
                            break;
                        case VRTF.ElementUsage.Tangent:
                            if (v.Tangents != null) foreach (float f in v.Tangents) w.Write(string.Format(" {0:F6}", f));
                            else w.Write(" Tangents is null.");
                            break;
                        case VRTF.ElementUsage.Colour:
                            if (v.Color != null) foreach (float f in v.Color) w.Write(string.Format(" {0:F6}", f));
                            else w.Write(" Colour is null.");
                            break;
                    }
                    w.WriteLine();
                    mpb.Value++;
                }
            }

            w.Flush();
            mpb.Done();
        }
Esempio n. 25
0
File: VBUF.cs Progetto: dd-dk/s3pi
        //Currently not supported:
        //UByte4N,
        //Short2N, Short4N, UShort2N,
        //Dec3N, UDec3N,
        //Float16_2, Float16_4
        public static void ReadFloatData(byte[] data, VRTF.ElementLayout layout, ref float[] output)
        {
            byte[] element = new byte[VRTF.ByteSizeFromFormat(layout.Format)];
            Array.Copy(data, layout.Offset, element, 0, element.Length);
            float scalar;

            switch (layout.Format)
            {
                case VRTF.ElementFormat.Float1:
                case VRTF.ElementFormat.Float2:
                case VRTF.ElementFormat.Float3:
                case VRTF.ElementFormat.Float4:
                    for (int i = 0; i < output.Length; i++)
                        output[i] += BitConverter.ToSingle(element, i * sizeof(float));
                    break;
                case VRTF.ElementFormat.ColorUByte4:
                    switch (layout.Usage)
                    {
                        case VRTF.ElementUsage.Colour:
                            for (int i = 0; i < output.Length; i++)
                                output[i] += element[i] / (float)byte.MaxValue;
                            break;
                        case VRTF.ElementUsage.BlendWeight:
                            for (int i = 0; i < output.Length; i++)
                                output[i] += element[kColorUByte4Map[i]] / (float)byte.MaxValue;
                            break;
                        case VRTF.ElementUsage.Normal:
                        case VRTF.ElementUsage.Tangent:
                            for (int i = 0; i < output.Length - 1; i++)
                                output[i] += element[2 - i] == 0 ? -1 : (((element[2 - i] + 1) / 128f) - 1);
                            //--
                            // Wes: (signed char) bytes[0]=vert[2+vrtfp.offset[j]];
                            //      (float)       norms[0]=(float)bytes[0];
                            //                    norms[0]=(norms[0]<(float)0.0)?(norms[0]+(float)128.0):(norms[0]-(float)128.0);
                            //???
                            //--
                            // input: 255 > 128 > 127 > 0
                            // map step1: +2 > 0
                            // map step2: +1 > -1
                            //for (int i = 0; i < output.Length - 1; i++)
                            //    output[i] += (element[2 - i] / 127.5f) - 1f;

                            switch (element[3])
                            {
                                case 0: output[output.Length - 1] = -1f; break; // -1 determinant
                                case 127: output[output.Length - 1] = 0f; break; // There is no determinant
                                case 255: output[output.Length - 1] = +1f; break; // +1 determinant
                                default: System.Diagnostics.Debug.WriteLine(String.Format("Unexpected handedness {0}.", element[3])); break;
                            }
                            break;
                    }
                    break;
                case VRTF.ElementFormat.Short2:
                    for (int i = 0; i < output.Length; i++)
                        output[i] += BitConverter.ToInt16(element, i * sizeof(short)) / (float)short.MaxValue;
                    break;
                case VRTF.ElementFormat.Short4:
                    scalar = BitConverter.ToUInt16(element, 3 * sizeof(short));
                    if (scalar == 0) scalar = short.MaxValue;
                    //scalar++;
                    for (int i = 0; i < output.Length; i++)
                        output[i] += BitConverter.ToInt16(element, i * sizeof(short)) / scalar;
                    break;
                case VRTF.ElementFormat.UShort4N:
                    scalar = BitConverter.ToUInt16(element, 3 * sizeof(ushort));
                    if (scalar == 0) scalar = 511;
                    //scalar++;
                    for (int i = 0; i < output.Length; i++)
                        output[i] += BitConverter.ToInt16(element, i * sizeof(short)) / scalar;
                    break;
            }
        }
Esempio n. 26
0
        public static void Import_VRTF(this StreamReader r, MyProgressBar mpb, VRTF vrtf)
        {
            string tagLine = r.ReadTag();
            string[] split;
            split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 3)
                throw new InvalidDataException("Invalid tag line read for 'vrtf'.");
            if (split[0] != "vrtf")
                throw new InvalidDataException("Expected line tag 'vrtf' not found.");
            int count;
            if (!int.TryParse(split[1], out count))
                throw new InvalidDataException("'vrtf' line has invalid count.");
            int stride;
            if (!int.TryParse(split[2], out stride))
                throw new InvalidDataException("'vrtf' line has invalid stride.");

            if (count == 0) return;
            vrtf.Layouts = new VRTF.VertexElementLayoutList(null);

            vrtf.Stride = stride;

            mpb.Init("Import VRTF...", count);
            for (int l = 0; l < count; l++)
            {
                split = r.ReadLine().Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
                if (split.Length != 5)
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has invalid format.", l));
                int index;
                if (!int.TryParse(split[0], out index))
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has invalid line index.", l));
                if (index != l)
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has incorrect line index value {1}.", l, index));
                byte[] values = split.ConvertAll<byte>(1);
                if (values.Length != 4)
                    throw new InvalidDataException(string.Format("'vrtf' line {0} has incorrect number of byte values {1}.", l, values.Length));

                vrtf.Layouts.Add(new VRTF.ElementLayout(0, null, (VRTF.ElementFormat)values[2], values[3], (VRTF.ElementUsage)values[0], values[1]));
                mpb.Value++;
            }
            mpb.Done();
        }
Esempio n. 27
0
File: VBUF.cs Progetto: 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;
 }
Esempio n. 28
0
        public static meshExpImp.ModelBlocks.Vertex[] Import_VBUF(this StreamReader r, MyProgressBar mpb, int count, VRTF vrtf)
        {
            meshExpImp.ModelBlocks.Vertex[] vertices = new meshExpImp.ModelBlocks.Vertex[count];
            int uvLength = vrtf.Layouts.FindAll(x => x.Usage == VRTF.ElementUsage.UV).Count;

            int line = 0;

            mpb.Init("Import VBUF...", count);
            for (int v = 0; v < count; v++)
            {
                meshExpImp.ModelBlocks.Vertex vertex = new meshExpImp.ModelBlocks.Vertex();
                int nUV = 0;
                vertex.UV = new float[uvLength][];

                foreach (var layout in vrtf.Layouts)
                {
                    string[] split = r.ReadLine().Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
                    if (split.Length < 2)
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid format.", line));
                    int index;
                    if (!int.TryParse(split[0], out index))
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid line index.", line));
                    if (index != v)
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line index value {1}.", line, index));
                    byte usage;
                    if (!byte.TryParse(split[1], out usage))
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid Usage.", v));
                    if (usage != (byte)layout.Usage)
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line Usage value {1}.", line, usage));

                    switch (usage)
                    {
                        case (byte)VRTF.ElementUsage.Position:
                            vertex.Position = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.Normal:
                            vertex.Normal = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.UV:
                            vertex.UV[nUV++] = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.BlendIndex:
                            byte[] BlendIndices = split.ConvertAll<byte>(2);
                            if (!(BlendIndices.Length == VRTF.ByteSizeFromFormat(layout.Format) || BlendIndices.Length + 1 == VRTF.ByteSizeFromFormat(layout.Format)))
                                throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect format.", line));
                            vertex.BlendIndices = BlendIndices;
                            break;
                        case (byte)VRTF.ElementUsage.BlendWeight:
                            vertex.BlendWeights = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.Tangent:
                            vertex.Tangents = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.Colour:
                            vertex.Color = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                    }
                    line++;
                }
                vertices[v] = vertex;
                if (nUV != uvLength)
                    throw new InvalidDataException(string.Format("'vbuf' vertex {0} read {1} UV lines, expected {2}.", v, nUV, uvLength));
                mpb.Value++;
            }
            mpb.Done();

            return vertices;
        }
Esempio n. 29
0
File: VBUF.cs Progetto: 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;
 }
Esempio n. 30
0
 static float[] GetFloats(VRTF.ElementFormat format, int line, float[] source)
 {
     float[] res = new float[VRTF.FloatCountFromFormat(format)];
     Array.Copy(source, res, Math.Min(source.Length, res.Length));
     return res;
 }
Esempio n. 31
0
File: VBUF.cs Progetto: dd-dk/s3pi
        private static void PositionMinMax(VRTF vrtf, IEnumerable<Vertex> vertices)
        {
            positionMin = 0f;
            positionMax = 0f;
            var layout = vrtf.Layouts.FirstOrDefault(x => x.Format == VRTF.ElementFormat.UShort4N && x.Usage == VRTF.ElementUsage.Position);
            if (layout == null) return;

            List<float> positionFloats = new List<float>();
            foreach (float[] fs in vertices.Select(x => x.Position))
                if (fs != null)
                    positionFloats.AddRange(fs);

            if (positionFloats.Count > 0)
            {
                positionMax = positionMin = Math.Abs(positionFloats[0]);
                foreach (float f in positionFloats)
                {
                    float x = Math.Abs(f);
                    if (positionMin > x) positionMin = x;
                    if (positionMax < x) positionMax = x;
                }
            }

            //positionMin = positionFloats.Count > 0 ? positionFloats.Min(x => Math.Abs(x)) : 0;
            //positionMax = positionFloats.Count > 0 ? positionFloats.Max(x => Math.Abs(x)) : 0;
        }
Esempio n. 32
0
        public List <offScale> VertsToVBUFs(GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, List <meshExpImp.ModelBlocks.Vertex[]> lmverts, 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]);

                    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);
        }
Esempio n. 33
0
File: VBUF.cs Progetto: dd-dk/s3pi
 private static void WritePositionData(float[] input, VRTF.ElementLayout layout, byte[] output, float max)
 {
     switch (layout.Format)
     {
         case VRTF.ElementFormat.UShort4N:
             //scalar = (max >= 1) ? 511 : (ulong)short.MaxValue;
             //-- could try "max < 1.0 / 512.0"?
             //ulong scalar = (ulong)(max < 1 ? short.MaxValue : 511);
             //scalar++;
             //2011-08-30 changed to fixed 512 as LoveseatDanishModern had problems
             ulong scalar = 512;
             for (int i = 0; i < input.Length; i++)
                 Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * scalar)), 0, output, layout.Offset + i * sizeof(short), sizeof(short));
             Array.Copy(BitConverter.GetBytes((short)(scalar == 512 ? 0 : scalar - 1)), 0, output, layout.Offset + 3 * sizeof(short), sizeof(short));
             break;
         default:
             WriteFloatData(input, layout, output);
             break;
     }
 }
Esempio n. 34
0
        //--


        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));
        }
Esempio n. 35
0
File: VBUF.cs Progetto: dd-dk/s3pi
        private static void WriteFloatData(float[] input, VRTF.ElementLayout layout, byte[] output)
        {
            ulong scalar;
            double max;

            switch (layout.Format)
            {
                case VRTF.ElementFormat.Float1:
                case VRTF.ElementFormat.Float2:
                case VRTF.ElementFormat.Float3:
                case VRTF.ElementFormat.Float4:
                    for (int i = 0; i < input.Length; i++)
                        Array.Copy(BitConverter.GetBytes(input[i]), 0, output, layout.Offset + i * sizeof(float), sizeof(float));
                    break;
                case VRTF.ElementFormat.ColorUByte4:
                    switch (layout.Usage)
                    {
                        case VRTF.ElementUsage.Colour:
                            for (int i = 0; i < input.Length; i++)
                                output[layout.Offset + i] = (byte)Math.Round(input[i] * byte.MaxValue);
                            break;
                        case VRTF.ElementUsage.BlendWeight:
                            for (int i = 0; i < input.Length; i++)
                                output[layout.Offset + kColorUByte4Map[i]] = (byte)Math.Round(input[i] * byte.MaxValue);
                            break;
                        case VRTF.ElementUsage.Normal:
                        case VRTF.ElementUsage.Tangent:
                            // -0.98828125 == (((0.5 + 1) / 128f) - 1)
                            for (int i = 0; i < input.Length - 1; i++)
                                output[layout.Offset + 2 - i] = (byte)(input[i] < -0.98828125 ? 0 : (Math.Round((input[i] + 1) * 128) - 1));
                            //--
                            // Wes: (signed char) bytes[0]=vert[2+vrtfp.offset[j]];
                            //      (float)       norms[0]=(float)bytes[0];
                            //                    norms[0]=(norms[0]<(float)0.0)?(norms[0]+(float)128.0):(norms[0]-(float)128.0);
                            //??
                            //--
                            // input: +1 > 0 > -1
                            // map step1: +2 > +1 > 0
                            // map step2: 255 > 127.5 > 0
                            //for (int i = 0; i < input.Length - 1; i++)
                            //    output[layout.Offset + 2 - i] = (byte)Math.Round((input[i] + 1) * 127.5);

                            if (input[input.Length - 1] == -1) output[layout.Offset + 3] = 0;
                            else if (input[input.Length - 1] == 0) output[layout.Offset + 3] = 127;
                            else if (input[input.Length - 1] == 1) output[layout.Offset + 3] = 255;
                            else
                                System.Diagnostics.Debug.WriteLine(String.Format("Unexpected handedness {0}.", input[input.Length - 1]));
                            break;
                    }
                    break;
                case VRTF.ElementFormat.Short2:
                    for (int i = 0; i < input.Length; i++)
                        Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * short.MaxValue)), 0, output, layout.Offset + i * sizeof(short), sizeof(short));
                    break;
                case VRTF.ElementFormat.Short4:
                    max = Math.Ceiling(input.Max(x => Math.Abs(x)));
                    scalar = (ulong)(max < 1 ? short.MaxValue : short.MaxValue / max);
                    //scalar++;
                    for (int i = 0; i < input.Length; i++)
                        Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * scalar)), 0, output, layout.Offset + i * sizeof(short), sizeof(short));
                    Array.Copy(BitConverter.GetBytes((short)(scalar /*- 1/**/)), 0, output, layout.Offset + 3 * sizeof(short), sizeof(short));
                    break;
                case VRTF.ElementFormat.UShort4N:
                    max = Math.Ceiling(input.Max(x => Math.Abs(x)));
                    scalar = (ulong)(max < 1.0 ? short.MaxValue : 512);
                    //scalar++;
                    for (int i = 0; i < input.Length; i++)
                        Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * scalar)), 0, output, layout.Offset + i * sizeof(short), sizeof(short));
                    Array.Copy(BitConverter.GetBytes((short)(scalar == 512 ? 0 : scalar /*- 1/**/)), 0, output, layout.Offset + 3 * sizeof(short), sizeof(short));
                    break;
            }
        }
Esempio n. 36
0
        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);
        }