public static BasicAttach ToBasic(this ChunkAttach cnkatt)
        {
            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.Resize(ref ColorBuffer, 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);
                    if (chunk.Diffuse.Count > 0)
                    {
                        Array.Copy(chunk.Diffuse.Cast <Color?>().ToArray(), 0, ColorBuffer, chunk.IndexOffset, chunk.Diffuse.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;
                    material.SourceAlpha      = c2.SourceAlpha;
                    material.DestinationAlpha = c2.DestinationAlpha;
                    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 hasStripVColor = false;
                    switch (chunk.Type)
                    {
                    case ChunkType.Strip_StripColor:
                    case ChunkType.Strip_StripUVNColor:
                    case ChunkType.Strip_StripUVHColor:
                        hasStripVColor = 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;
                    }
                    bool hasVertVColor = false;
                    if (!hasStripVColor && c2.Strips.All(a => a.Indexes.All(b => ColorBuffer[b].HasValue)))
                    {
                        hasVertVColor = true;
                    }
                    bool         hasVColor = hasStripVColor || hasVertVColor;
                    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((ushort[])strip.Indexes.Clone(), strip.Reversed));
                        if (hasUV)
                        {
                            uvs.AddRange(strip.UVs);
                        }
                        if (hasStripVColor)
                        {
                            vcolors.AddRange(strip.VColors);
                        }
                        else if (hasVertVColor)
                        {
                            foreach (short i in strip.Indexes)
                            {
                                vcolors.Add(ColorBuffer[i].Value);
                            }
                        }
                    }
                    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);
                    }
                }
            }
            return(basatt);
        }
Exemple #2
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().Trim('"');
            }
            LandTable level = LandTable.LoadFromFile(filename);
            Dictionary <string, Attach> visitedAttaches = new Dictionary <string, Attach>();

            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 & SA1SurfaceFlags.Visible) == SA1SurfaceFlags.Visible)
                    {
                        COL newcol = new COL()
                        {
                            Bounds = col.Bounds
                        };
                        newcol.SurfaceFlags = SA1SurfaceFlags.Visible;
                        newcol.Model        = new 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;
                        string      newname = basatt.Name + "_cnk";
                        if (visitedAttaches.ContainsKey(newname))
                        {
                            newcol.Model.Attach = visitedAttaches[newname];
                        }
                        else
                        {
                            ChunkAttach cnkatt = basatt.ToChunk();
                            visitedAttaches[newname] = cnkatt;
                            newcol.Model.Attach      = cnkatt;
                        }
                        newcollist.Add(newcol);
                    }
                    if ((col.SurfaceFlags & ~SA1SurfaceFlags.Visible) != 0)
                    {
                        col.SurfaceFlags &= ~SA1SurfaceFlags.Visible;
                        newcollist.Add(col);
                    }
                }
                level.COL = newcollist;
            }
                level.Anim = new List <GeoAnimData>();
                level.SaveToFile(System.IO.Path.ChangeExtension(filename, "sa2lvl"), LandTableFormat.SA2);
                break;

            case LandTableFormat.SA2:
                foreach (COL col in level.COL.Where((col) => col.Model != null && col.Model.Attach is ChunkAttach))
                {
                    col.Model.Attach = col.Model.Attach.ToBasic();
                }
                level.Anim  = new List <GeoAnimData>();
                level.Flags = 8;                         // set LandTable to use PVM/GVM
                level.SaveToFile(System.IO.Path.ChangeExtension(filename, "sa1lvl"), LandTableFormat.SA1);
                break;
            }
        }