public static List <PolyChunk> Merge(List <PolyChunk> source) { var strips = new List <(NJS_MATERIAL mat, List <PolyChunk> pre, PolyChunkStrip str)>(); NJS_MATERIAL curmat = new NJS_MATERIAL(); var cnks = new List <PolyChunk>(); foreach (var chunk in source) { curmat.UpdateFromPolyChunk(chunk); if (chunk is PolyChunkStrip str) { bool found = false; foreach (var set in strips) { if (set.mat.Equals(curmat) && set.str.Type == str.Type) { found = true; set.str.Strips.AddRange(str.Strips); break; } } if (!found) { strips.Add((curmat, cnks, str)); } curmat = new NJS_MATERIAL(curmat); cnks = new List <PolyChunk>(); } else { cnks.Add(chunk); } } return(strips.SelectMany(a => a.pre.Append(a.str)).ToList()); }
private List <MeshInfo> ProcessPolyList(string name, List <PolyChunk> strips, int start) { List <MeshInfo> result = new List <MeshInfo>(); for (int i = start; i < strips.Count; i++) { PolyChunk chunk = strips[i]; MaterialBuffer.UpdateFromPolyChunk(chunk); switch (chunk.Type) { case ChunkType.Bits_CachePolygonList: byte cachenum = ((PolyChunkBitsCachePolygonList)chunk).List; #if modellog Extensions.Log("Caching Poly List " + name + "[" + (i + 1) + "] to cache #" + cachenum + Environment.NewLine); #endif PolyCache[cachenum] = new CachedPoly(name, strips, i + 1); return(result); case ChunkType.Bits_DrawPolygonList: cachenum = ((PolyChunkBitsDrawPolygonList)chunk).List; CachedPoly cached = PolyCache[cachenum]; #if modellog Extensions.Log("Drawing Poly List " + cached.Name + "[" + cached.Index + "] from cache #" + cachenum + Environment.NewLine); #endif result.AddRange(ProcessPolyList(cached.Name, cached.Polys, cached.Index)); break; case ChunkType.Strip_Strip: case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripNormal: case ChunkType.Strip_StripUVNNormal: case ChunkType.Strip_StripUVHNormal: case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_Strip2: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: { PolyChunkStrip c2 = (PolyChunkStrip)chunk; #if modellog Extensions.Log("Strip " + c2.Type + Environment.NewLine); #endif bool hasVColor = false; switch (chunk.Type) { case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: hasVColor = true; break; } bool hasUV = false; switch (chunk.Type) { case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: hasUV = true; break; } List <Poly> polys = new List <Poly>(); List <VertexData> verts = new List <VertexData>(); #if modellog List <ushort> indexes = new List <ushort>(); #endif foreach (PolyChunkStrip.Strip strip in c2.Strips) { #if modellog indexes.AddRange(strip.Indexes); #endif Strip str = new Strip(strip.Indexes.Length, strip.Reversed); for (int k = 0; k < strip.Indexes.Length; k++) { str.Indexes[k] = (ushort)verts.Count; verts.Add(new VertexData( VertexBuffer[strip.Indexes[k]].Position, VertexBuffer[strip.Indexes[k]].Normal, hasVColor ? (Color?)strip.VColors[k] : VertexBuffer[strip.Indexes[k]].Color, hasUV ? strip.UVs[k] : null)); } polys.Add(str); } if (!hasVColor) { hasVColor = verts.Any(a => a.Color.HasValue && a.Color.Value != Color.White); } #if modellog indexes = new List <ushort>(System.Linq.Enumerable.Distinct(indexes)); indexes.Sort(); StringBuilder sb = new StringBuilder("Vertex Usage: "); ushort ist = indexes[0]; for (int k = 0; k < indexes.Count - 1; k++) { if (indexes[k + 1] != indexes[k] + 1) { sb.Append(" " + ist); if (indexes[k] != ist) { sb.Append("-" + indexes[k]); } ist = indexes[++k]; } } sb.Append(" " + ist); if (indexes[indexes.Count - 1] != ist) { sb.Append("-" + indexes[indexes.Count - 1]); } sb.Append(Environment.NewLine); Extensions.Log(sb.ToString()); #endif result.Add(new MeshInfo(MaterialBuffer, polys.ToArray(), verts.ToArray(), hasUV, hasVColor)); MaterialBuffer = new NJS_MATERIAL(MaterialBuffer); } break; } } return(result); }