/// <summary> /// Initialize a new <see cref="RWMeshMaterialSplitData"/> using a <see cref="RWMesh"/> and the primitive type for the split data. /// </summary> /// <param name="mesh"></param> /// <param name="primType"></param> public RWMeshMaterialSplitData(RWMesh mesh, RWPrimitiveType primType = RWPrimitiveType.TriangleStrip, RWNode parent = null) : base(RWNodeType.MeshMaterialSplitList, parent) { // set type and prim count _primType = primType; _numPrimitives = mesh.TriangleCount; // pass 1: order the triangles by ascending material id var sortedTriangles = mesh.Triangles.OrderBy(tri => tri.MatID).ToArray(); // pass 2: split the indices List<ushort>[] matSplitsIndices = new List<ushort>[mesh.MaterialCount]; List<ushort> curMatSplitIndices = null; int curMatIdx = -1; for (int i = 0; i < sortedTriangles.Length; i++) { var tri = sortedTriangles[i]; if (tri.MatID > curMatIdx) { if (curMatIdx != -1) matSplitsIndices[curMatIdx] = curMatSplitIndices; curMatIdx = tri.MatID; curMatSplitIndices = new List<ushort>(); } curMatSplitIndices.Add(tri.A); curMatSplitIndices.Add(tri.B); curMatSplitIndices.Add(tri.C); } matSplitsIndices[curMatIdx] = curMatSplitIndices; // pass 3: create the split data _splits = new RWMeshMaterialSplit[mesh.MaterialCount]; for (int i = 0; i < _splits.Length; i++) { ushort[] matSplitIndices = matSplitsIndices[i].ToArray(); if (primType == RWPrimitiveType.TriangleStrip) { ManagedNvTriStrip.PrimitiveGroup[] primitives = null; if (ManagedNvTriStrip.NvTriStripUtility.Stripify(matSplitIndices, ref primitives)) { matSplitIndices = primitives[0].Indices; } else { throw new System.Exception("Failed to generate strips."); } /* NvTriStripDotNet.PrimitiveGroup[] primitives; var tristripper = new NvTriStripDotNet.NvTriStrip(); if (tristripper.GenerateStrips(matSplitIndices, out primitives)) { matSplitIndices = primitives[0].indices.Cast<ushort>().ToArray(); } */ } _splits[i] = new RWMeshMaterialSplit(i, matSplitIndices); } }
// init with factory node info & binary reader internal RWMeshMaterialSplitData(RWNodeFactory.RWNodeInfo header, BinaryReader reader) : base(header) { _primType = (RWPrimitiveType)reader.ReadUInt32(); int numSplits = reader.ReadInt32(); _numPrimitives = reader.ReadInt32(); _splits = new RWMeshMaterialSplit[numSplits]; for (int i = 0; i < numSplits; i++) { _splits[i] = new RWMeshMaterialSplit(reader); } }