Exemplo n.º 1
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();
            }
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        //--


        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));
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
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));
        }