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()); }
public MeshInfo(NJS_MATERIAL material, Poly[] polys, VertexData[] vertices, bool hasUV, bool hasVC) { Material = material; Polys = polys; Vertices = vertices; HasUV = hasUV; HasVC = hasVC; }
/// <summary> /// Use this if you need a copy of a material. /// </summary> /// <param name="copy"></param> public NJS_MATERIAL(NJS_MATERIAL copy) { DiffuseColor = copy.DiffuseColor; SpecularColor = copy.SpecularColor; Exponent = copy.Exponent; TextureID = copy.TextureID; Flags = copy.Flags; }
public void UpdateFlags(NJS_MATERIAL mat) { IgnoreLight = mat.IgnoreLighting; IgnoreSpecular = mat.IgnoreSpecular; IgnoreAmbient = mat.IgnoreAmbient; UseAlpha = mat.UseAlpha; DoubleSide = mat.DoubleSided; FlatShading = mat.FlatShading; EnvironmentMapping = mat.EnvironmentMap; }
public override void Init(ObjectData data, string name, Device dev) { mesh = Mesh.Box(dev, 1f, 1f, 1f); material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(180, 180, 180, 180), UseAlpha = true }; texture = new Texture(dev, new Bitmap(2, 2), 0, Pool.Managed); }
public override bool Equals(object obj) { if (!(obj is NJS_MATERIAL)) { return(false); } NJS_MATERIAL other = (NJS_MATERIAL)obj; return(AmbientColor == other.AmbientColor && DiffuseColor == other.DiffuseColor && SpecularColor == other.SpecularColor && Exponent == other.Exponent && TextureID == other.TextureID && Flags == other.Flags); }
public PolyChunkTinyTextureID(NJS_MATERIAL mat) : this() { MipmapDAdjust = mat.MipmapDAdjust; ClampV = mat.ClampV; ClampU = mat.ClampU; FlipV = mat.FlipV; FlipU = mat.FlipU; TextureID = (ushort)mat.TextureID; SuperSample = mat.SuperSample; FilterMode = mat.FilterMode; }
public override void ProcessVertexData() { List <MeshInfo> result = new List <MeshInfo>(); foreach (NJS_MESHSET mesh in Mesh) { bool hasVColor = mesh.VColor != null; bool hasUV = mesh.UV != null; List <Poly> polys = new List <Poly>(); List <VertexData> verts = new List <VertexData>(); int currentstriptotal = 0; foreach (Poly poly in mesh.Poly) { Poly newpoly = null; switch (mesh.PolyType) { case Basic_PolyType.Triangles: newpoly = new Triangle(); break; case Basic_PolyType.Quads: newpoly = new Quad(); break; case Basic_PolyType.NPoly: case Basic_PolyType.Strips: newpoly = new Strip(poly.Indexes.Length, ((Strip)poly).Reversed); break; } for (int i = 0; i < poly.Indexes.Length; i++) { newpoly.Indexes[i] = (ushort)verts.Count; verts.Add(new VertexData( Vertex[poly.Indexes[i]], Normal[poly.Indexes[i]], hasVColor ? (Color?)mesh.VColor[currentstriptotal] : null, hasUV ? mesh.UV[currentstriptotal++] : null)); } polys.Add(newpoly); } NJS_MATERIAL mat = null; if (Material != null && mesh.MaterialID < Material.Count) { mat = Material[mesh.MaterialID]; } result.Add(new MeshInfo(mat, polys.ToArray(), verts.ToArray(), hasUV, hasVColor)); } MeshInfo = result.ToArray(); }
public PolyChunkMaterial(NJS_MATERIAL mat) { SourceAlpha = mat.SourceAlpha; DestinationAlpha = mat.DestinationAlpha; Diffuse = mat.DiffuseColor; if (mat.AmbientColor != Color.White) { Ambient = mat.AmbientColor; } if (mat.SpecularColor != Color.Transparent) { Specular = mat.SpecularColor; SpecularExponent = (byte)mat.Exponent; } }
public override void ProcessShapeMotionVertexData(NJS_MOTION motion, int frame, int animindex) { if (!motion.Models.ContainsKey(animindex)) { ProcessVertexData(); return; } Vertex[] vertdata = Vertex; Vertex[] normdata = Normal; AnimModelData data = motion.Models[animindex]; if (data.Vertex.Count > 0) { vertdata = data.GetVertex(frame); } if (data.Normal.Count > 0) { normdata = data.GetNormal(frame); } List <MeshInfo> result = new List <MeshInfo>(); foreach (NJS_MESHSET mesh in Mesh) { bool hasVColor = mesh.VColor != null; bool hasUV = mesh.UV != null; List <Poly> polys = new List <Poly>(); List <VertexData> verts = new List <VertexData>(); int currentstriptotal = 0; foreach (Poly poly in mesh.Poly) { Poly newpoly = null; switch (mesh.PolyType) { case Basic_PolyType.Triangles: newpoly = new Triangle(); break; case Basic_PolyType.Quads: newpoly = new Quad(); break; case Basic_PolyType.NPoly: case Basic_PolyType.Strips: newpoly = new Strip(poly.Indexes.Length, ((Strip)poly).Reversed); break; } for (int i = 0; i < poly.Indexes.Length; i++) { newpoly.Indexes[i] = (ushort)verts.Count; verts.Add(new VertexData( vertdata[poly.Indexes[i]], normdata[poly.Indexes[i]], hasVColor ? (Color?)mesh.VColor[currentstriptotal] : null, hasUV ? mesh.UV[currentstriptotal++] : null)); } polys.Add(newpoly); } NJS_MATERIAL mat = null; if (Material != null && mesh.MaterialID < Material.Count) { mat = Material[mesh.MaterialID]; } result.Add(new MeshInfo(mat, polys.ToArray(), verts.ToArray(), hasUV, hasVColor)); } MeshInfo = result.ToArray(); }
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); }
static void Main(string[] args) { string filename; if (args.Length > 0) { filename = args[0]; Console.WriteLine("File: {0}", filename); } else { Console.Write("File: "); filename = Console.ReadLine(); } LandTable level = LandTable.LoadFromFile(filename); switch (level.Format) { case LandTableFormat.SA1: { List<COL> newcollist = new List<COL>(); foreach (COL col in level.COL.Where((col) => col.Model != null && col.Model.Attach != null)) { if ((col.SurfaceFlags & SurfaceFlags.Visible) == SurfaceFlags.Visible) { COL newcol = new COL() { Bounds = col.Bounds }; newcol.SurfaceFlags = SurfaceFlags.Visible; newcol.Model = new SonicRetro.SAModel.NJS_OBJECT() { Name = col.Model.Name + "_cnk" }; newcol.Model.Position = col.Model.Position; newcol.Model.Rotation = col.Model.Rotation; newcol.Model.Scale = col.Model.Scale; BasicAttach basatt = (BasicAttach)col.Model.Attach; ChunkAttach cnkatt = new ChunkAttach(true, true) { Name = basatt.Name + "_cnk", Bounds = basatt.Bounds }; newcol.Model.Attach = cnkatt; VertexChunk vcnk; if (basatt.Normal != null && basatt.Normal.Length > 0) vcnk = new VertexChunk(ChunkType.Vertex_VertexNormal); else vcnk = new VertexChunk(ChunkType.Vertex_Vertex); vcnk.Vertices = new List<Vertex>(basatt.Vertex); if (basatt.Normal != null) vcnk.Normals = new List<Vertex>(basatt.Normal); vcnk.VertexCount = (ushort)basatt.Vertex.Length; vcnk.Size = (ushort)((vcnk.Type == ChunkType.Vertex_VertexNormal ? vcnk.VertexCount * 6 : vcnk.VertexCount * 3) + 1); cnkatt.Vertex.Add(vcnk); foreach (NJS_MESHSET mesh in basatt.Mesh) { if (mesh.PolyType != Basic_PolyType.Strips) { Console.WriteLine("Warning: Skipping non-strip mesh in {0} ({1}).", basatt.MeshName, mesh.PolyType); continue; } NJS_MATERIAL mat = null; if (basatt.Material != null && mesh.MaterialID < basatt.Material.Count) { mat = basatt.Material[mesh.MaterialID]; cnkatt.Poly.Add(new PolyChunkBitsBlendAlpha() { SourceAlpha = mat.SourceAlpha, DestinationAlpha = mat.DestinationAlpha }); cnkatt.Poly.Add(new PolyChunkTinyTextureID() { ClampU = mat.ClampU, ClampV = mat.ClampV, FilterMode = mat.FilterMode, FlipU = mat.FlipU, FlipV = mat.FlipV, SuperSample = mat.SuperSample, TextureID = (ushort)mat.TextureID }); cnkatt.Poly.Add(new PolyChunkMaterial() { Diffuse = mat.DiffuseColor, Specular = mat.SpecularColor, SpecularExponent = (byte)mat.Exponent }); } PolyChunkStrip strip; if (mesh.UV != null & mesh.VColor != null) strip = new PolyChunkStrip(ChunkType.Strip_StripUVNColor); else if (mesh.UV != null) strip = new PolyChunkStrip(ChunkType.Strip_StripUVN); else if (mesh.VColor != null) strip = new PolyChunkStrip(ChunkType.Strip_StripColor); else strip = new PolyChunkStrip(ChunkType.Strip_Strip); if (mat != null) { strip.IgnoreLight = mat.IgnoreLighting; strip.IgnoreSpecular = mat.IgnoreSpecular; strip.UseAlpha = mat.UseAlpha; strip.DoubleSide = mat.DoubleSided; strip.FlatShading = mat.FlatShading; strip.EnvironmentMapping = mat.EnvironmentMap; } int striptotal = 0; foreach (Strip item in mesh.Poly.Cast<Strip>()) { UV[] uvs = null; if (mesh.UV != null) { uvs = new UV[item.Indexes.Length]; Array.Copy(mesh.UV, striptotal, uvs, 0, item.Indexes.Length); } Color[] vcolors = null; if (mesh.VColor != null) { vcolors = new Color[item.Indexes.Length]; Array.Copy(mesh.VColor, striptotal, vcolors, 0, item.Indexes.Length); } strip.Strips.Add(new PolyChunkStrip.Strip(item.Reversed, item.Indexes, uvs, vcolors)); striptotal += item.Indexes.Length; } cnkatt.Poly.Add(strip); } newcollist.Add(newcol); } if ((col.SurfaceFlags & ~SurfaceFlags.Visible) != 0) { col.SurfaceFlags &= ~SurfaceFlags.Visible; newcollist.Add(col); } } level.COL = newcollist; } level.Anim = new List<GeoAnimData>(); level.Tool = "SA Tools Level Converter"; level.SaveToFile(System.IO.Path.ChangeExtension(filename, "sa2lvl"), LandTableFormat.SA2); break; case LandTableFormat.SA2: Vertex[] VertexBuffer = new Vertex[0]; Vertex[] NormalBuffer = new Vertex[0]; foreach (COL col in level.COL.Where((col) => col.Model != null && col.Model.Attach is ChunkAttach)) { ChunkAttach cnkatt = (ChunkAttach)col.Model.Attach; BasicAttach basatt = new BasicAttach() { Name = cnkatt.Name, Bounds = cnkatt.Bounds }; if (cnkatt.Vertex != null) foreach (VertexChunk chunk in cnkatt.Vertex) { if (VertexBuffer.Length < chunk.IndexOffset + chunk.VertexCount) { Array.Resize(ref VertexBuffer, chunk.IndexOffset + chunk.VertexCount); Array.Resize(ref NormalBuffer, chunk.IndexOffset + chunk.VertexCount); } Array.Copy(chunk.Vertices.ToArray(), 0, VertexBuffer, chunk.IndexOffset, chunk.Vertices.Count); Array.Copy(chunk.Normals.ToArray(), 0, NormalBuffer, chunk.IndexOffset, chunk.Normals.Count); } NJS_MATERIAL material = new NJS_MATERIAL() { UseTexture = true }; int minVtx = int.MaxValue; int maxVtx = int.MinValue; foreach (PolyChunk chunk in cnkatt.Poly) switch (chunk.Type) { case ChunkType.Bits_BlendAlpha: { PolyChunkBitsBlendAlpha c2 = (PolyChunkBitsBlendAlpha)chunk; material.SourceAlpha = c2.SourceAlpha; material.DestinationAlpha = c2.DestinationAlpha; } break; case ChunkType.Bits_MipmapDAdjust: break; case ChunkType.Bits_SpecularExponent: material.Exponent = ((PolyChunkBitsSpecularExponent)chunk).SpecularExponent; break; case ChunkType.Tiny_TextureID: case ChunkType.Tiny_TextureID2: { PolyChunkTinyTextureID c2 = (PolyChunkTinyTextureID)chunk; material.ClampU = c2.ClampU; material.ClampV = c2.ClampV; material.FilterMode = c2.FilterMode; material.FlipU = c2.FlipU; material.FlipV = c2.FlipV; material.SuperSample = c2.SuperSample; material.TextureID = c2.TextureID; } break; case ChunkType.Material_Diffuse: case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: { PolyChunkMaterial c2 = (PolyChunkMaterial)chunk; if (c2.Diffuse.HasValue) material.DiffuseColor = c2.Diffuse.Value; if (c2.Specular.HasValue) { material.SpecularColor = c2.Specular.Value; material.Exponent = c2.SpecularExponent; } } 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; material.DoubleSided = c2.DoubleSide; material.EnvironmentMap = c2.EnvironmentMapping; material.FlatShading = c2.FlatShading; material.IgnoreLighting = c2.IgnoreLight; material.IgnoreSpecular = c2.IgnoreSpecular; material.UseAlpha = c2.UseAlpha; 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<Strip> strips = new List<Strip>(c2.StripCount); List<UV> uvs = hasUV ? new List<UV>() : null; List<Color> vcolors = hasVColor ? new List<Color>() : null; foreach (PolyChunkStrip.Strip strip in c2.Strips) { minVtx = Math.Min(minVtx, strip.Indexes.Min()); maxVtx = Math.Max(maxVtx, strip.Indexes.Max()); strips.Add(new Strip(strip.Indexes, strip.Reversed)); if (hasUV) uvs.AddRange(strip.UVs); if (hasVColor) vcolors.AddRange(strip.VColors); } NJS_MESHSET mesh = new NJS_MESHSET(strips.ToArray(), false, hasUV, hasVColor); if (hasUV) uvs.CopyTo(mesh.UV); if (hasVColor) vcolors.CopyTo(mesh.VColor); mesh.MaterialID = (ushort)basatt.Material.Count; basatt.Mesh.Add(mesh); basatt.Material.Add(material); material = new NJS_MATERIAL(material.GetBytes(), 0); } break; } int numVtx = maxVtx - minVtx + 1; basatt.ResizeVertexes(numVtx); Array.Copy(VertexBuffer, minVtx, basatt.Vertex, 0, numVtx); Array.Copy(NormalBuffer, minVtx, basatt.Normal, 0, numVtx); foreach (NJS_MESHSET mesh in basatt.Mesh) foreach (Poly poly in mesh.Poly) for (int i = 0; i < poly.Indexes.Length; i++) poly.Indexes[i] = (ushort)(poly.Indexes[i] - minVtx); col.Model.Attach = basatt; } level.Anim = new List<GeoAnimData>(); level.Tool = "SA Tools Level Converter"; level.SaveToFile(System.IO.Path.ChangeExtension(filename, "sa1lvl"), LandTableFormat.SA1); break; } }
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]; switch (chunk.Type) { case ChunkType.Bits_BlendAlpha: { PolyChunkBitsBlendAlpha c2 = (PolyChunkBitsBlendAlpha)chunk; MaterialBuffer.SourceAlpha = c2.SourceAlpha; MaterialBuffer.DestinationAlpha = c2.DestinationAlpha; } break; case ChunkType.Bits_MipmapDAdjust: break; case ChunkType.Bits_SpecularExponent: MaterialBuffer.Exponent = ((PolyChunkBitsSpecularExponent)chunk).SpecularExponent; break; 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.Tiny_TextureID: case ChunkType.Tiny_TextureID2: { PolyChunkTinyTextureID c2 = (PolyChunkTinyTextureID)chunk; MaterialBuffer.ClampU = c2.ClampU; MaterialBuffer.ClampV = c2.ClampV; MaterialBuffer.FilterMode = c2.FilterMode; MaterialBuffer.FlipU = c2.FlipU; MaterialBuffer.FlipV = c2.FlipV; MaterialBuffer.SuperSample = c2.SuperSample; MaterialBuffer.TextureID = c2.TextureID; } break; case ChunkType.Material_Diffuse: case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: { PolyChunkMaterial c2 = (PolyChunkMaterial)chunk; MaterialBuffer.SourceAlpha = c2.SourceAlpha; MaterialBuffer.DestinationAlpha = c2.DestinationAlpha; if (c2.Diffuse.HasValue) { MaterialBuffer.DiffuseColor = c2.Diffuse.Value; } if (c2.Specular.HasValue) { MaterialBuffer.SpecularColor = c2.Specular.Value; MaterialBuffer.Exponent = c2.SpecularExponent; } } 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 MaterialBuffer.DoubleSided = c2.DoubleSide; MaterialBuffer.EnvironmentMap = c2.EnvironmentMapping; MaterialBuffer.FlatShading = c2.FlatShading; MaterialBuffer.IgnoreLighting = c2.IgnoreLight; MaterialBuffer.IgnoreSpecular = c2.IgnoreSpecular; MaterialBuffer.UseAlpha = c2.UseAlpha; 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 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); }
private List<MeshInfo> ProcessPolyList(List<PolyChunk> strips, int start) { List<MeshInfo> result = new List<MeshInfo>(); for (int i = start; i < strips.Count; i++) { PolyChunk chunk = strips[i]; switch (chunk.Type) { case ChunkType.Bits_BlendAlpha: { PolyChunkBitsBlendAlpha c2 = (PolyChunkBitsBlendAlpha)chunk; MaterialBuffer.SourceAlpha = c2.SourceAlpha; MaterialBuffer.DestinationAlpha = c2.DestinationAlpha; } break; case ChunkType.Bits_MipmapDAdjust: break; case ChunkType.Bits_SpecularExponent: MaterialBuffer.Exponent = ((PolyChunkBitsSpecularExponent)chunk).SpecularExponent; break; case ChunkType.Bits_CachePolygonList: PolyCache[((PolyChunkBitsCachePolygonList)chunk).List] = new CachedPoly(strips, i + 1); return result; case ChunkType.Bits_DrawPolygonList: byte cachenum = ((PolyChunkBitsDrawPolygonList)chunk).List; CachedPoly cached = PolyCache[cachenum]; PolyCache[cachenum] = null; result.AddRange(ProcessPolyList(cached.Polys, cached.Index)); break; case ChunkType.Tiny_TextureID: case ChunkType.Tiny_TextureID2: { PolyChunkTinyTextureID c2 = (PolyChunkTinyTextureID)chunk; MaterialBuffer.ClampU = c2.ClampU; MaterialBuffer.ClampV = c2.ClampV; MaterialBuffer.FilterMode = c2.FilterMode; MaterialBuffer.FlipU = c2.FlipU; MaterialBuffer.FlipV = c2.FlipV; MaterialBuffer.SuperSample = c2.SuperSample; MaterialBuffer.TextureID = c2.TextureID; } break; case ChunkType.Material_Diffuse: case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: { PolyChunkMaterial c2 = (PolyChunkMaterial)chunk; if (c2.Diffuse.HasValue) MaterialBuffer.DiffuseColor = c2.Diffuse.Value; if (c2.Specular.HasValue) { MaterialBuffer.SpecularColor = c2.Specular.Value; MaterialBuffer.Exponent = c2.SpecularExponent; } } 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; MaterialBuffer.DoubleSided = c2.DoubleSide; MaterialBuffer.EnvironmentMap = c2.EnvironmentMapping; MaterialBuffer.FlatShading = c2.FlatShading; MaterialBuffer.IgnoreLighting = c2.IgnoreLight; MaterialBuffer.IgnoreSpecular = c2.IgnoreSpecular; MaterialBuffer.UseAlpha = c2.UseAlpha; 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>(); foreach (PolyChunkStrip.Strip strip in c2.Strips) { Strip str = new Strip(strip.Indexes.Length, strip.Reversed); for (int k = 0; k < strip.Indexes.Length; k++) { str.Indexes[k] = (ushort)verts.AddUnique(new VertexData( VertexBuffer[strip.Indexes[k]], NormalBuffer[strip.Indexes[k]], hasVColor ? (Color?)strip.VColors[k] : null, hasUV ? strip.UVs[k] : null)); } polys.Add(str); } result.Add(new MeshInfo(MaterialBuffer, polys.ToArray(), verts.ToArray(), hasUV, hasVColor)); MaterialBuffer = new NJS_MATERIAL(MaterialBuffer); } break; } } return result; }