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(); }
private IEnumerable<offScale> getOffScales(int meshGroup, int geoState, meshExpImp.ModelBlocks.Vertex[] verts, float[] uvScales) { for (int v = 0; v < verts.Length; v++) foreach (float[] uvs in verts[v].UV) for (int u = 0; u < uvs.Length; u++) { float max = (u < uvScales.Length && uvScales[u] != 0 ? uvScales[u] : uvScales[0]) * short.MaxValue; if (uvs[u] > max) yield return new offScale() { meshGroup = meshGroup, geoState = geoState, vertex = v, nUV = u, actual = uvs[u], max = max }; } }
//-- 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 }
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); }