예제 #1
0
파일: PolyChunk.cs 프로젝트: inrg/sa_tools
        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());
        }
예제 #2
0
 public MeshInfo(NJS_MATERIAL material, Poly[] polys, VertexData[] vertices, bool hasUV, bool hasVC)
 {
     Material = material;
     Polys    = polys;
     Vertices = vertices;
     HasUV    = hasUV;
     HasVC    = hasVC;
 }
예제 #3
0
 /// <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;
 }
예제 #4
0
 /// <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;
 }
예제 #5
0
파일: PolyChunk.cs 프로젝트: inrg/sa_tools
 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;
 }
예제 #6
0
 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);
 }
예제 #7
0
        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);
        }
예제 #8
0
파일: PolyChunk.cs 프로젝트: inrg/sa_tools
 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;
 }
예제 #9
0
        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();
        }
예제 #10
0
파일: PolyChunk.cs 프로젝트: inrg/sa_tools
 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;
     }
 }
예제 #11
0
        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();
        }
예제 #12
0
        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);
        }
예제 #13
0
 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;
     }
 }
예제 #14
0
        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);
        }
예제 #15
0
 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;
 }