Пример #1
0
        public override void Process(SceneReaderContext context)
        {
            context.VerifyWorld("Texture");

            var textureParams = new TextureParams(Parameters, Parameters,
                context.GraphicsState.FloatTextures,
                context.GraphicsState.SpectrumTextures);

            switch (TextureType)
            {
                case "float" :
                {
                    context.GraphicsState.FloatTextures[Name] = Factories.MakeFloatTexture(
                        TextureClass, context.CurrentTransform[0],
                        textureParams); ;
                    break;
                }
                case "color" :
                case "spectrum" :
                {
                    context.GraphicsState.SpectrumTextures[Name] = Factories.MakeSpectrumTexture(
                        TextureClass, context.CurrentTransform[0],
                        textureParams); ;
                    break;
                }
                default :
                    throw new InvalidOperationException("Texture type '" + TextureType +" ' unknown.");
            }
        }
Пример #2
0
 public void AddTextureParams(string name, TextureParams texture)
 {
     lock (textures)
     {
         textures.Add(name, texture);
     }
 }
Пример #3
0
 private void Initialize(TextureParams textureParams)
 {
     compressed = Format.IsCompressed();
     GLHelper.GetGLTextureFormat(Context, Format, out GLInternalFormat, out GLFormat, out GLPixelType);
     GLTexture = GL.GenTexture();
     GLHelper.CheckGLErrors();
     GL.ActiveTexture(TextureUnit.Texture0);
     GLHelper.CheckGLErrors();
     GL.BindTexture(TextureTarget.Texture2D, GLTexture);
     GLHelper.CheckGLErrors();
     for (var level = 0; level < LevelCount; level++)
     {
         GraphicsUtility.CalculateMipLevelSize(level, Width, Height, out var levelWidth, out var levelHeight);
         if (compressed)
         {
             var imageSize = GraphicsUtility.CalculateImageDataSize(Format, levelWidth, levelHeight);
             GL.CompressedTexImage2D(TextureTarget.Texture2D, level, (PixelInternalFormat)GLInternalFormat,
                                     levelWidth, levelHeight, 0, imageSize, IntPtr.Zero);
             GLHelper.CheckGLErrors();
         }
         else
         {
             GL.TexImage2D(TextureTarget.Texture2D, level, (PixelInternalFormat)GLInternalFormat,
                           levelWidth, levelHeight, 0, (PixelFormat)GLFormat, (PixelType)GLPixelType, IntPtr.Zero);
             GLHelper.CheckGLErrors();
         }
     }
     UpdateTextureParams(textureParams);
     Context.InvalidateTextureBinding(0);
 }
Пример #4
0
        public override void Process(SceneReaderContext context)
        {
            context.VerifyWorld("Texture");

            var textureParams = new TextureParams(Parameters, Parameters,
                                                  context.GraphicsState.FloatTextures,
                                                  context.GraphicsState.SpectrumTextures);

            switch (TextureType)
            {
            case "float":
            {
                context.GraphicsState.FloatTextures[Name] = Factories.MakeFloatTexture(
                    TextureClass, context.CurrentTransform[0],
                    textureParams);;
                break;
            }

            case "color":
            case "spectrum":
            {
                context.GraphicsState.SpectrumTextures[Name] = Factories.MakeSpectrumTexture(
                    TextureClass, context.CurrentTransform[0],
                    textureParams);;
                break;
            }

            default:
                throw new InvalidOperationException("Texture type '" + TextureType + " ' unknown.");
            }
        }
Пример #5
0
 public Texture Parameters(TextureParams parameters)
 {
     if (parameters != null)
     {
         using (Scope())
         {
             foreach (var param in parameters)
             {
                 if (param.Item2 is int || param.Item2.GetType().IsEnum)
                 {
                     GL.TexParameter(_target, param.Item1, (int)param.Item2);
                 }
                 else if (param.Item2 is float)
                 {
                     GL.TexParameter(_target, param.Item1, (float)param.Item2);
                 }
                 else
                 {
                     throw new ArgumentException("Unsupported texture parameter Item2 type: " +
                                                 param.Item2.GetType());
                 }
             }
         }
     }
     return(this);
 }
Пример #6
0
        private void UpdateTextureParams()
        {
            var rules = Orange.CookingRulesBuilder.Build(Orange.The.Workspace.AssetFiles, null);

            foreach (var kv in rules)
            {
                var path = kv.Key;
                var rule = kv.Value;
                if (path.EndsWith(".png"))
                {
                    var textureParamsPath = Path.Combine(Orange.The.Workspace.AssetsDirectory, Path.ChangeExtension(path, ".texture"));
                    if (!Orange.AssetCooker.AreTextureParamsDefault(rule))
                    {
                        var textureParams = new TextureParams {
                            WrapMode  = rule.WrapMode,
                            MinFilter = rule.MinFilter,
                            MagFilter = rule.MagFilter,
                        };
                        Serialization.WriteObjectToFile(textureParamsPath, textureParams, Serialization.Format.JSON);
                    }
                    else if (File.Exists(textureParamsPath))
                    {
                        File.Delete(textureParamsPath);
                    }
                }
                else if (path.EndsWith(".texture") && !File.Exists(Path.Combine(AssetsDirectory, Path.ChangeExtension(path, ".png"))))
                {
                    File.Delete(Path.Combine(AssetsDirectory, path));
                }
            }
        }
Пример #7
0
        public static void ImportTexture(string path, Bitmap texture, ICookingRules rules, byte[] CookingRulesSHA1)
        {
            var textureParamsPath = Path.ChangeExtension(path, ".texture");

            if (!AreTextureParamsDefault(rules))
            {
                UpscaleTextureIfNeeded(ref texture, rules, false);
                var textureParams = new TextureParams {
                    WrapMode  = rules.WrapMode,
                    MinFilter = rules.MinFilter,
                    MagFilter = rules.MagFilter,
                };
                Serialization.WriteObjectToBundle(AssetBundle, textureParamsPath, textureParams, Serialization.Format.Binary, ".texture", AssetAttributes.None, null);
            }
            else
            {
                if (AssetBundle.FileExists(textureParamsPath))
                {
                    DeleteFileFromBundle(textureParamsPath);
                }
            }
            if (ShouldGenerateOpacityMasks())
            {
                var maskPath = Path.ChangeExtension(path, ".mask");
                OpacityMaskCreator.CreateMask(AssetBundle, texture, maskPath);
            }
            var attributes = AssetAttributes.ZippedDeflate;

            if (!TextureConverterUtils.IsPowerOf2(texture.Width) || !TextureConverterUtils.IsPowerOf2(texture.Height))
            {
                attributes |= AssetAttributes.NonPowerOf2Texture;
            }
            switch (Platform)
            {
            case TargetPlatform.Android:
                var f = rules.PVRFormat;
                if (f == PVRFormat.ARGB8 || f == PVRFormat.RGB565 || f == PVRFormat.RGBA4)
                {
                    TextureConverter.RunPVRTexTool(texture, AssetBundle, path, attributes, rules.MipMaps, rules.HighQualityCompression, rules.PVRFormat, CookingRulesSHA1);
                }
                else
                {
                    TextureConverter.RunEtcTool(texture, AssetBundle, path, attributes, rules.MipMaps, rules.HighQualityCompression, CookingRulesSHA1);
                }
                break;

            case TargetPlatform.iOS:
                TextureConverter.RunPVRTexTool(texture, AssetBundle, path, attributes, rules.MipMaps, rules.HighQualityCompression, rules.PVRFormat, CookingRulesSHA1);
                break;

            case TargetPlatform.Win:
            case TargetPlatform.Mac:
                TextureConverter.RunNVCompress(texture, AssetBundle, path, attributes, rules.DDSFormat, rules.MipMaps, CookingRulesSHA1);
                break;

            default:
                throw new Lime.Exception();
            }
        }
        public override void Process(SceneReaderContext context)
        {
            context.VerifyWorld("MakeNamedMaterial");

            var textureParams = new TextureParams(Parameters, context.GraphicsState.MaterialParams,
                context.GraphicsState.FloatTextures, context.GraphicsState.SpectrumTextures);
            context.GraphicsState.NamedMaterials[MaterialName] = Factories.MakeMaterial(
                MaterialType, context.CurrentTransform[0], textureParams);
        }
Пример #9
0
 public void SetTextureParams(TextureParams textureParams)
 {
     GL.ActiveTexture(TextureUnit.Texture0);
     GLHelper.CheckGLErrors();
     GL.BindTexture(TextureTarget.Texture2D, GLTexture);
     GLHelper.CheckGLErrors();
     UpdateTextureParams(textureParams);
     Context.InvalidateTextureBinding(0);
 }
Пример #10
0
        public override void Process(SceneReaderContext context)
        {
            context.VerifyWorld("MakeNamedMaterial");

            var textureParams = new TextureParams(Parameters, context.GraphicsState.MaterialParams,
                                                  context.GraphicsState.FloatTextures, context.GraphicsState.SpectrumTextures);

            context.GraphicsState.NamedMaterials[MaterialName] = Factories.MakeMaterial(
                MaterialType, context.CurrentTransform[0], textureParams);
        }
Пример #11
0
        private static long CalculateHash(TextureParams textureParams)
        {
            var hasher = new Hasher();

            hasher.Begin();
            hasher.Write(textureParams.MinFilter);
            hasher.Write(textureParams.MagFilter);
            hasher.Write(textureParams.MipmapMode);
            hasher.Write(textureParams.WrapModeU);
            hasher.Write(textureParams.WrapModeV);
            return(hasher.End());
        }
Пример #12
0
        public SharpVulkan.Sampler AcquireSampler(TextureParams textureParams)
        {
            textureParams = textureParams ?? TextureParams.Default;
            var hash = CalculateHash(textureParams);

            if (!cache.TryGetValue(hash, out var sampler))
            {
                sampler = CreateSampler(textureParams);
                cache.Add(hash, sampler);
            }
            return(sampler);
        }
Пример #13
0
        private SharpVulkan.Sampler CreateSampler(TextureParams textureParams)
        {
            var createInfo = new SharpVulkan.SamplerCreateInfo {
                StructureType = SharpVulkan.StructureType.SamplerCreateInfo,
                MinFilter     = GetVKFilter(textureParams.MinFilter),
                MagFilter     = GetVKFilter(textureParams.MagFilter),
                MipmapMode    = GetVKSamplerMipmapMode(textureParams.MipmapMode),
                AddressModeU  = GetVKSamplerAddressMode(textureParams.WrapModeU),
                AddressModeV  = GetVKSamplerAddressMode(textureParams.WrapModeV)
            };

            return(context.Device.CreateSampler(ref createInfo));
            // FIXME: Adjust MinLod, MaxLod to match OpenGL
        }
Пример #14
0
        public TextureParams GetTextureParams(string name)
        {
            TextureParams param = null;

            lock (textures)
            {
                if (!textures.TryGetValue(name, out param))
                {
                    param = null;
                }
            }

            return(param);
        }
Пример #15
0
        private void UpdateTextureParams()
        {
            var rules = CookingRulesBuilder.Build(The.Workspace.AssetFiles, null);

            foreach (var kv in rules)
            {
                var path = kv.Key;
                var rule = kv.Value;
                if (path.EndsWith(".png"))
                {
                    var textureParamsPath = Path.Combine(The.Workspace.AssetsDirectory, Path.ChangeExtension(path, ".texture"));
                    if (!AssetCooker.AreTextureParamsDefault(rule))
                    {
                        var textureParams = new TextureParams {
                            WrapMode  = rule.WrapMode,
                            MinFilter = rule.MinFilter,
                            MagFilter = rule.MagFilter,
                        };
                        // buz: перед тем, как сохранять файл, надо убедиться, что там ещё не создан файл с точно такими же параметрами.
                        // Потому что в зависимости от настроек системы/гита/Аллаха у сохраняемых файлов получаются разные line endings,
                        // и если их постоянно перезаписывать, то они вечно будут показываться как изменённые в git, что жутко бесит,
                        // и мешает работать.
                        if (File.Exists(textureParamsPath))
                        {
                            try {
                                var existingParams = TangerinePersistence.Instance.ReadObjectFromFile <TextureParams>(textureParamsPath);
                                if (existingParams.Equals(textureParams))
                                {
                                    continue;
                                }
                            } catch (Exception) {
                                // Подавляем исключения сериализации, потому что я не хочу, чтобы
                                // этот костыль ещё и валил Танжерин по хз какому поводу.
                            }
                        }
                        TangerinePersistence.Instance.WriteObjectToFile(textureParamsPath, textureParams, Persistence.Format.Json);
                    }
                    else if (File.Exists(textureParamsPath))
                    {
                        File.Delete(textureParamsPath);
                    }
                }
                else if (path.EndsWith(".texture") && !File.Exists(Path.Combine(AssetsDirectory, Path.ChangeExtension(path, ".png"))))
                {
                    File.Delete(Path.Combine(AssetsDirectory, path));
                }
            }
        }
Пример #16
0
        private void UpdateTextureParams(TextureParams textureParams)
        {
            textureParams = textureParams ?? TextureParams.Default;
            var glMinFilter = LevelCount > 1
                                ? GLHelper.GetGLTextureFilter(textureParams.MinFilter, textureParams.MipmapMode)
                                : GLHelper.GetGLTextureFilter(textureParams.MinFilter);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)glMinFilter);
            GLHelper.CheckGLErrors();
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
                            (int)GLHelper.GetGLTextureFilter(textureParams.MagFilter));
            GLHelper.CheckGLErrors();
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
                            (int)GLHelper.GetGLTextureWrapMode(textureParams.WrapModeU));
            GLHelper.CheckGLErrors();
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
                            (int)GLHelper.GetGLTextureWrapMode(textureParams.WrapModeV));
            GLHelper.CheckGLErrors();
        }
Пример #17
0
        public void ImportTexture(string path, Bitmap texture, ICookingRules rules, DateTime time, byte[] CookingRulesSHA1)
        {
            var textureParamsPath = Path.ChangeExtension(path, ".texture");
            var textureParams     = new TextureParams {
                WrapMode  = rules.WrapMode,
                MinFilter = rules.MinFilter,
                MagFilter = rules.MagFilter,
            };

            if (!AreTextureParamsDefault(rules))
            {
                TextureTools.UpscaleTextureIfNeeded(ref texture, rules, false);
                var isNeedToRewriteTexParams = true;
                if (AssetBundle.FileExists(textureParamsPath))
                {
                    var oldTexParams = InternalPersistence.Instance.ReadObject <TextureParams>(textureParamsPath, AssetBundle.OpenFile(textureParamsPath));
                    isNeedToRewriteTexParams = !oldTexParams.Equals(textureParams);
                }
                if (isNeedToRewriteTexParams)
                {
                    InternalPersistence.Instance.WriteObjectToBundle(AssetBundle, textureParamsPath, textureParams, Persistence.Format.Binary, ".texture",
                                                                     File.GetLastWriteTime(textureParamsPath), AssetAttributes.None, null);
                }
            }
            else
            {
                if (AssetBundle.FileExists(textureParamsPath))
                {
                    DeleteFileFromBundle(textureParamsPath);
                }
            }
            if (rules.GenerateOpacityMask)
            {
                var maskPath = Path.ChangeExtension(path, ".mask");
                OpacityMaskCreator.CreateMask(AssetBundle, texture, maskPath);
            }
            var attributes = AssetAttributes.ZippedDeflate;

            if (!TextureConverterUtils.IsPowerOf2(texture.Width) || !TextureConverterUtils.IsPowerOf2(texture.Height))
            {
                attributes |= AssetAttributes.NonPowerOf2Texture;
            }
            switch (Target.Platform)
            {
            case TargetPlatform.Android:
                //case TargetPlatform.iOS:
                var f = rules.PVRFormat;
                if (f == PVRFormat.ARGB8 || f == PVRFormat.RGB565 || f == PVRFormat.RGBA4)
                {
                    TextureConverter.RunPVRTexTool(texture, AssetBundle, path, attributes, rules.MipMaps, rules.HighQualityCompression, rules.PVRFormat, CookingRulesSHA1, time);
                }
                else
                {
                    TextureConverter.RunEtcTool(texture, AssetBundle, path, attributes, rules.MipMaps, rules.HighQualityCompression, CookingRulesSHA1, time);
                }
                break;

            case TargetPlatform.iOS:
                TextureConverter.RunPVRTexTool(texture, AssetBundle, path, attributes, rules.MipMaps, rules.HighQualityCompression, rules.PVRFormat, CookingRulesSHA1, time);
                break;

            case TargetPlatform.Win:
            case TargetPlatform.Mac:
                TextureConverter.RunNVCompress(texture, AssetBundle, path, attributes, rules.DDSFormat, rules.MipMaps, CookingRulesSHA1, time);
                break;

            default:
                throw new Lime.Exception();
            }
        }
Пример #18
0
 internal PlatformRenderTexture2D(PlatformRenderContext context, Format format, int width, int height, TextureParams textureParams)
     : base(context, format, width, height, false, textureParams)
 {
     Initialize();
 }
Пример #19
0
 internal PlatformTexture2D(PlatformRenderContext context, Format format, int width, int height, bool mipmaps, TextureParams textureParams)
 {
     Context    = context;
     Format     = format;
     Width      = width;
     Height     = height;
     LevelCount = mipmaps ? GraphicsUtility.CalculateMipLevelCount(width, height) : 1;
     Initialize(textureParams);
 }
Пример #20
0
 public PlatformRenderTexture2D(PlatformRenderContext context, Format format, int width, int height, TextureParams textureParams)
     : base(context, format, width, height, false, true, textureParams)
 {
     colorFormat = VulkanHelper.GetVKFormat(format);
     CreateDepthStencilBuffer();
     CreateRenderPass();
     CreateFramebuffer();
 }
Пример #21
0
 public IPlatformTexture2D CreateTexture2D(Format format, int width, int height, bool mipmaps, TextureParams textureParams)
 {
     return(new PlatformTexture2D(this, format, width, height, mipmaps, textureParams));
 }
Пример #22
0
 protected PlatformTexture2D(PlatformRenderContext context, Format format, int width, int height, bool mipmaps, bool renderTarget, TextureParams textureParams)
 {
     this.context    = context;
     this.format     = format;
     this.width      = width;
     this.height     = height;
     this.levelCount = mipmaps ? GraphicsUtility.CalculateMipLevelCount(width, height) : 1;
     Create(renderTarget);
     SetTextureParams(textureParams);
 }
Пример #23
0
 public PlatformTexture2D(PlatformRenderContext context, Format format, int width, int height, bool mipmaps, TextureParams textureParams)
     : this(context, format, width, height, mipmaps, false, textureParams)
 {
 }
Пример #24
0
 public void SetTextureParams(TextureParams textureParams)
 {
     sampler = context.SamplerCache.AcquireSampler(textureParams);
 }
Пример #25
0
 public IPlatformRenderTexture2D CreateRenderTexture2D(Format format, int width, int height, TextureParams textureParams)
 {
     return(new PlatformRenderTexture2D(this, format, width, height, textureParams));
 }
Пример #26
0
        public static Model LoadFile(System.IO.Stream stream)
        {
            var buffer = FlatBuffers.Gfbmdl.Model.GetRootAsModel(
                new FlatBuffers.ByteBuffer(stream.ToBytes()));

            Model model = new Model();

            model.Version  = buffer.Version;
            model.Bounding = ConvertBounding(buffer.Bounding);

            model.TextureNames  = new List <string>();
            model.ShaderNames   = new List <string>();
            model.MaterialNames = new List <string>();

            for (int i = 0; i < buffer.TextureNamesLength; i++)
            {
                model.TextureNames.Add(buffer.TextureNames(i));
            }

            for (int i = 0; i < buffer.ShaderNamesLength; i++)
            {
                model.ShaderNames.Add(buffer.ShaderNames(i));
            }

            for (int i = 0; i < buffer.MaterialNamesLength; i++)
            {
                model.MaterialNames.Add(buffer.MaterialNames(i));
            }

            model.Materials = new List <Material>();
            for (int i = 0; i < buffer.MaterialsLength; i++)
            {
                var               mat      = buffer.Materials(i).Value;
                List <MatColor>   colors   = new List <MatColor>();
                List <MatSwitch>  switches = new List <MatSwitch>();
                List <MatFloat>   values   = new List <MatFloat>();
                List <TextureMap> textures = new List <TextureMap>();

                MaterialCommon common = null;
                if (mat.Common != null)
                {
                    var com = mat.Common.Value;

                    List <MatColor>  sharedColors   = new List <MatColor>();
                    List <MatSwitch> sharedSwitches = new List <MatSwitch>();
                    List <MatInt>    sharedValues   = new List <MatInt>();

                    for (int j = 0; j < com.ColorsLength; j++)
                    {
                        var col = com.Colors(j).Value;
                        sharedColors.Add(new MatColor()
                        {
                            Color = ConvertColor(col.Color),
                            Name  = col.Name,
                        });
                    }

                    for (int j = 0; j < com.ValuesLength; j++)
                    {
                        var val = com.Values(j).Value;
                        sharedValues.Add(new MatInt()
                        {
                            Value = val.Value,
                            Name  = val.Name,
                        });
                    }

                    for (int j = 0; j < com.SwitchesLength; j++)
                    {
                        var val = com.Switches(j).Value;
                        sharedSwitches.Add(new MatSwitch()
                        {
                            Value = val.Value,
                            Name  = val.Name,
                        });
                    }

                    common = new MaterialCommon()
                    {
                        Switches = sharedSwitches,
                        Values   = sharedValues,
                        Colors   = sharedColors,
                    };
                }

                for (int j = 0; j < mat.TextureMapsLength; j++)
                {
                    var           tex        = mat.TextureMaps(j).Value;
                    TextureParams parameters = null;
                    if (tex.Params != null)
                    {
                        var param = tex.Params.Value;
                        parameters = new TextureParams()
                        {
                            Unknown1  = param.Unknown1,
                            WrapModeX = (uint)param.WrapModeX,
                            WrapModeY = (uint)param.WrapModeY,
                            WrapModeZ = (uint)param.WrapModeZ,
                            Unknown5  = param.Unknown5,
                            Unknown6  = param.Unknown6,
                            Unknown7  = param.Unknown7,
                            Unknown8  = param.Unknown8,
                            lodBias   = param.LodBias,
                        };
                    }
                    textures.Add(new TextureMap()
                    {
                        Index   = (uint)tex.Index,
                        Sampler = tex.Sampler,
                        Params  = parameters,
                    });
                }

                for (int j = 0; j < mat.ColorsLength; j++)
                {
                    var col = mat.Colors(j).Value;
                    colors.Add(new MatColor()
                    {
                        Color = ConvertColor(col.Color),
                        Name  = col.Name,
                    });
                }

                for (int j = 0; j < mat.ValuesLength; j++)
                {
                    var val = mat.Values(j).Value;
                    values.Add(new MatFloat()
                    {
                        Value = val.Value,
                        Name  = val.Name,
                    });
                }

                for (int j = 0; j < mat.SwitchesLength; j++)
                {
                    var val = mat.Switches(j).Value;
                    switches.Add(new MatSwitch()
                    {
                        Value = val.Value,
                        Name  = val.Name,
                    });
                }

                if (mat.Parameter3 != i)
                {
                    Console.WriteLine($"Expected {i} for shader index, got " + mat.Parameter3);
                }
                if (mat.Parameter4 != -1)
                {
                    Console.WriteLine("Expected -1 for param 4, got " + mat.Parameter4);
                }
                if (mat.Parameter5 != i)
                {
                    Console.WriteLine($"Expected {i} for param 5, got " + mat.Parameter5);
                }

                model.Materials.Add(new Material()
                {
                    Name        = mat.Name,
                    Switches    = switches,
                    Colors      = colors,
                    Values      = values,
                    Parameter1  = mat.Parameter1,
                    Parameter2  = mat.Parameter2,
                    Parameter3  = mat.Parameter3,
                    ShaderIndex = mat.ShaderIndex,
                    Parameter4  = mat.Parameter4,
                    Parameter5  = mat.Parameter5,
                    RenderLayer = mat.RenderLayer,
                    ShaderGroup = mat.ShaderGroup,
                    Unknown1    = mat.Unknown1,
                    Unknown2    = mat.Unknown2,
                    Unknown3    = mat.Unknown3,
                    Unknown4    = mat.Unknown4,
                    Unknown5    = mat.Unknown5,
                    Unknown6    = mat.Unknown6,
                    Unknown7    = mat.Unknown7,
                    Common      = common,
                    TextureMaps = textures,
                });
            }

            model.Groups = new List <Group>();
            for (int i = 0; i < buffer.GroupsLength; i++)
            {
                var group = buffer.Groups(i).Value;
                model.Groups.Add(new Group()
                {
                    BoneIndex = group.BoneIndex,
                    Layer     = group.Layer,
                    MeshIndex = group.MeshIndex,
                    Bounding  = ConvertBounding(group.Bounding),
                });
            }

            model.Meshes = new List <Mesh>();
            for (int i = 0; i < buffer.MeshesLength; i++)
            {
                var mesh = buffer.Meshes(i).Value;

                List <MeshAttribute> attributes = new List <MeshAttribute>();
                for (int j = 0; j < mesh.AttributesLength; j++)
                {
                    var att = mesh.Attributes(j).Value;
                    attributes.Add(new MeshAttribute()
                    {
                        BufferFormat = att.BufferFormat,
                        ElementCount = att.ElementCount,
                        VertexType   = att.VertexType,
                    });
                }

                List <MeshPolygon> polygons = new List <MeshPolygon>();
                for (int j = 0; j < mesh.PolygonsLength; j++)
                {
                    var poly = mesh.Polygons(j).Value;
                    polygons.Add(new MeshPolygon()
                    {
                        MaterialIndex = poly.MaterialIndex,
                        Faces         = poly.GetFacesArray().ToList(),
                    });
                }

                model.Meshes.Add(new Mesh()
                {
                    Attributes = attributes,
                    Polygons   = polygons,
                    Data       = mesh.GetDataArray().ToList(),
                });
            }

            model.Bones = new List <Bone>();
            for (int i = 0; i < buffer.BonesLength; i++)
            {
                var           bone      = buffer.Bones(i).Value;
                BoneRigidData rigidData = null;
                if (bone.RigidCheck != null)
                {
                    rigidData          = new BoneRigidData();
                    rigidData.Unknown1 = (uint)bone.RigidCheck.Value.Unknown1;
                }

                model.Bones.Add(new Bone()
                {
                    Name        = bone.Name,
                    BoneType    = bone.BoneType,
                    Parent      = bone.Parent,
                    Scale       = ConvertVec3(bone.Scale),
                    Rotation    = ConvertVec3(bone.Rotation),
                    Translation = ConvertVec3(bone.Translation),
                    RadiusEnd   = ConvertVec3(bone.RadiusEnd),
                    RadiusStart = ConvertVec3(bone.RadiusStart),
                    Visible     = bone.Visible,
                    Zero        = bone.Zero,
                    RigidCheck  = rigidData,
                });
            }

            model.CollisionGroups = new List <CollisionGroup>();
            for (int i = 0; i < buffer.CollisionGroupsLength; i++)
            {
                var         colGroup = buffer.CollisionGroups(i).Value;
                List <uint> children = colGroup.GetBoneChildrenArray().ToList();

                model.CollisionGroups.Add(new CollisionGroup()
                {
                    BoneIndex    = colGroup.BoneIndex,
                    Unknown1     = colGroup.Unknown1,
                    Bounding     = ConvertBounding(colGroup.Bounding),
                    BoneChildren = children,
                });
            }

            model.Unknown = new List <UnknownEmpty>();

            return(model);
        }