Example #1
0
 protected virtual TextureModel OnLoadEmbeddedTexture(EmbeddedTexture texture)
 {
     if (texture.HasCompressedData)
     {
         logger.LogInformation("Loading Embedded Compressed Texture. Format: {}", texture.CompressedFormatHint);
         if (!SupportedTextureFormatDict.Contains(texture.CompressedFormatHint.ToLowerInvariant()))
         {
             logger.LogInformation("Compressed Texture Format not supported. Format: {}", texture.CompressedFormatHint);
             return(null);
         }
         var data   = texture.CompressedData.ToArray();
         var stream = new MemoryStream(data);
         return(new TextureModel(stream));
     }
     else if (texture.HasNonCompressedData)
     {
         logger.LogInformation("Loading Embedded NonCompressed Texture");
         var rawData = texture.NonCompressedData.Select(x => new Color4(x.R / 255f, x.G / 255f, x.B / 255f, x.A / 255f)).ToArray();
         return(new TextureModel(rawData, texture.Width, texture.Height));
     }
     else
     {
         return(null);
     }
 }
Example #2
0
        /// <summary>
        /// Populates the TextureSet with all the textures required for the scene.
        /// </summary>
        private void LoadTextures()
        {
            var materials = _raw.Materials;

            foreach (var mat in materials)
            {
                var textures = mat.GetAllMaterialTextures();
                foreach (var tex in textures)
                {
                    var             path           = tex.FilePath;
                    EmbeddedTexture embeddedSource = null;
                    if (path.StartsWith("*"))
                    {
                        // Embedded texture, following the asterisk is the zero-based
                        // index of the data source in Assimp.Scene.Textures
                        uint index;
                        if (Raw.HasTextures && uint.TryParse(path.Substring(1), out index) && index < Raw.TextureCount)
                        {
                            embeddedSource = Raw.Textures[(int)index];
                        }
                        // else: just add the name to the texture set without specifying
                        // a data source, the texture will then be in a failed state
                        // but users can still replace it manually.
                    }

                    TextureSet.Add(tex.FilePath, embeddedSource);
                }
            }

            TextureSet.AddCallback((name, tex) =>
            {
                SetTexturesChangedFlag();
                return(true);
            });
        }
        /// <summary>
        /// Converts a texture embedded in the model to a domain texture.
        /// </summary>
        /// <param name="embeddedTexture">The embedded texture to convert.</param>
        /// <returns>The resulting domain texture.</returns>
        private DomainTexture ConvertToDomainTexture(EmbeddedTexture embeddedTexture)
        {
            if (embeddedTexture.IsCompressed)
            {
                var extension     = $".{embeddedTexture.CompressedFormatHint}";
                var textureReader = _textureReaders.FirstOrDefault(s => s.IsExtensionSupported(extension));
                if (textureReader == null)
                {
                    throw new Exception($"No available reader for loading embedded texture with extension '{extension}'.");
                }

                // Don't automatically dispose of the stream here, as it may be necessary for the final loading
                // process, at which point the stream will be disposed of afterwards.
                var memoryStream = new MemoryStream(embeddedTexture.CompressedData);

                return(textureReader.Read(memoryStream, string.Empty, extension));
            }

            var bytes = new byte[embeddedTexture.Width * embeddedTexture.Height * 4];
            int index = 0;

            foreach (var texel in embeddedTexture.NonCompressedData)
            {
                bytes[index]     = texel.R;
                bytes[index + 1] = texel.G;
                bytes[index + 2] = texel.B;
                bytes[index + 3] = texel.A;
                index           += 4;
            }

            return(new DomainTexture(embeddedTexture.Width, embeddedTexture.Height, TextureFormat.Rgba32, new ReadOnlyCollection <byte>(bytes)));
        }
Example #4
0
        public static Texture LoadTextureFromEmbeddedTexture(EmbeddedTexture embeddedTexture)
        {
            try {
                if (embeddedTexture.IsCompressed)
                {
                    Image <Rgba32> image = Image.Load(embeddedTexture.CompressedData);
                    return(Texture.CreateTexture(image));
                }
                else
                {
                    Console.WriteLine("Embedded texture is NOT compressed, needs to be implemented");
                }
            } catch (Exception e) {
                Console.WriteLine("ERROR: Failed to load embedded texture " + e.Message);
            }

            return(null);
        }
Example #5
0
        private SEAObject AppendTexture(EmbeddedTexture texture)
        {
            int sIndex = GetIndexByTag(texture);

            if (sIndex != -1)
            {
                return((SEATexture)Writer.Objects[sIndex]);
            }

            SEATexture tex = new SEATexture(GetValidString(textures, "EmbeddedTexture"), texture.CompressedFormatHint.ToLower());

            tex.Data.WriteBytes(texture.CompressedData);
            tex.tag = texture;

            textures.Add(tex);
            Writer.AddObject(tex);

            return(tex);
        }
        public void TestEmbeddedTexture()
        {
            Scene           scene = new Scene();
            EmbeddedTexture tex1  = new EmbeddedTexture();

            tex1.Filename = "Terrain.bmp";
            scene.Textures.Add(tex1);

            EmbeddedTexture tex2 = new EmbeddedTexture();

            tex2.Filename = "Grass.png";
            scene.Textures.Add(tex2);

            EmbeddedTexture texQuery = scene.GetEmbeddedTexture("*1");

            Assert.IsTrue(texQuery == tex2);

            texQuery = scene.GetEmbeddedTexture("C:/TextureFolder/Terrains/Terrain.bmp");
            Assert.IsTrue(texQuery == tex1);
        }
Example #7
0
        public static GameTexture ConvertToTexture(EmbeddedTexture tex)
        {
            tex.Log($"Loading Texture... Width: {tex.Width} Height: {tex.Height}", DebugChannel.Log, 8);
            GameTexture ret = new GameTexture();

            GL.BindTexture(TextureTarget.Texture2D, ret.textureID);

            byte[] flatBytes = flattenImageData(tex.NonCompressedData);

            GCHandle handle = GCHandle.Alloc(flatBytes, GCHandleType.Pinned);
            IntPtr   ptr    = handle.AddrOfPinnedObject();


            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, tex.Width, tex.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, ptr);

            handle.Free();

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

            return(ret);
        }
Example #8
0
 void TestTexture(EmbeddedTexture netTexture, AssimpSharp.Texture sharpTexture)
 {
     throw (new NotImplementedException());
 }
        public void Fix(IModel model, Scene sc)
        {
            // Imports the textures
            var finTextures = new HashSet <ITexture>();

            foreach (var finMaterial in model.MaterialManager.All)
            {
                foreach (var finTexture in finMaterial.Textures)
                {
                    finTextures.Add(finTexture);
                }
            }

            var originalMaterialOrder =
                sc.Materials.Select(material => material.Name).ToArray();

            sc.Textures.Clear();

            foreach (var finTexture in finTextures)
            {
                var imageData = finTexture.ImageData;

                var imageBytes = new MemoryStream();
                imageData.Save(imageBytes, ImageFormat.Png);

                var assTexture =
                    new EmbeddedTexture("png",
                                        imageBytes.ToArray(),
                                        finTexture.Name);
                assTexture.Filename = finTexture.Name + ".png";

                sc.Textures.Add(assTexture);
            }

            // Need to keep order the same because Assimp references them by index.
            for (var m = 0; m < originalMaterialOrder.Length; ++m)
            {
                var originalMaterialName = originalMaterialOrder[m];
                var finMaterial          =
                    model.MaterialManager.All
                    .FirstOrDefault(finMaterial
                                    => finMaterial.Name ==
                                    originalMaterialName);

                if (finMaterial == null)
                {
                    continue;
                }

                var assMaterial = new Material {
                    Name = finMaterial.Name
                };

                var finTexture = PrimaryTextureFinder.GetFor(finMaterial);
                if (finTexture != null)
                {
                    var assTextureSlot = new TextureSlot {
                        FilePath = finTexture.Name + ".png",
                        // TODO: FBX doesn't support mirror. Blegh
                        WrapModeU = this.ConvertWrapMode_(finTexture.WrapModeU),
                        WrapModeV = this.ConvertWrapMode_(finTexture.WrapModeV)
                    };

                    assTextureSlot.TextureType = Assimp.TextureType.Diffuse;
                    assTextureSlot.UVIndex     = finTexture.UvIndex;

                    assMaterial.AddMaterialTexture(assTextureSlot);
                }

                // Meshes should already have material indices set.
                sc.Materials[m] = assMaterial;
            }
        }
Example #10
0
        protected override void CreateInternal(ReadOnlyMemory <byte> data)
        {
            var str = new ReadOnlyLinkedMemoryStream();

            str.AddMemory(data);

            _assContext ??= new AssimpContext();
            Scene scene = _assContext.ImportFileFromStream(str,
                                                           PostProcessSteps.Triangulate |
                                                           PostProcessSteps.FlipUVs |
                                                           PostProcessSteps.OptimizeGraph |
                                                           PostProcessSteps.OptimizeMeshes);

            var embeddedTextures = new List <Texture>();

            for (var i = 0; i < scene.TextureCount; i++)
            {
                EmbeddedTexture assTexture      = scene.Textures[i];
                var             embeddedTexture = new TextureAsset();
                embeddedTexture.Create(assTexture.CompressedData);
                embeddedTextures.Add(embeddedTexture.Texture);
            }

            _materials = new List <MeshMaterial>();
            for (var i = 0; i < scene.MaterialCount; i++)
            {
                Material material  = scene.Materials[i];
                Color4D  diffColor = material.ColorDiffuse;

                bool embeddedTexture = material.HasTextureDiffuse && embeddedTextures.Count > material.TextureDiffuse.TextureIndex;
                var  emotionMaterial = new MeshMaterial
                {
                    Name               = material.Name,
                    DiffuseColor       = new Color(new Vector4(diffColor.R, diffColor.G, diffColor.B, diffColor.A)),
                    DiffuseTextureName = embeddedTexture ? $"EmbeddedTexture{material.TextureDiffuse.TextureIndex}" : null,
                    DiffuseTexture     = embeddedTexture ? embeddedTextures[material.TextureDiffuse.TextureIndex] : null
                };

                _materials.Add(emotionMaterial);
            }

            _animations = new List <SkeletalAnimation>();
            ProcessAnimations(scene);

            _meshes = new List <Mesh>();
            Node rootNode = scene.RootNode;
            SkeletonAnimRigNode animRigRoot = ProcessNode(scene, rootNode);

            animRigRoot.LocalTransform *= Matrix4x4.CreateRotationX(-90 * Maths.DEG2_RAD); // Convert to right handed Z is up.

            Entity = new MeshEntity
            {
                Name         = Name,
                Meshes       = _meshes.ToArray(),
                Animations   = _animations.ToArray(),
                AnimationRig = animRigRoot
            };

            object scaleData = scene.RootNode.Metadata.GetValueOrDefault("UnitScaleFactor").Data;
            var    scaleF    = 1f;

            if (scaleData is float f)
            {
                scaleF = f;
            }
            Entity.Scale = scaleF;
        }
Example #11
0
 public TextureNode(EmbeddedTexture texture)
 {
     _texture = texture;
 }
Example #12
0
 //Maybe create key for textures loaded with assimp and then use them as cache name
 /// <summary>
 /// Converts an Assimp Texture into a Engine/OpenGL Texture
 /// </summary>
 /// <param name="tex">Assimp texture</param>
 /// <returns>GL Texure</returns>
 public static Texture AssimpEmbeddedToTexture(EmbeddedTexture tex, object handleIdentifier)
 {
     return(BytesToTexture(flattenImageData(tex.NonCompressedData), tex.Width, tex.Height, handleIdentifier));
 }
        public EmbeddedTextureLoader(EmbeddedTexture tex)
        {
            if (tex.IsCompressed)
            {
                var compTex = tex;
                if (!compTex.HasCompressedData)
                {
                    return;
                }

                // note: have to keep the stream open for the lifetime of the image, so don't Dispose()
                SetFromStream(new MemoryStream(compTex.CompressedData));
                return;
            }

            var rawTex = tex;

            if (!rawTex.HasNonCompressedData || rawTex.Width < 1 || rawTex.Height < 1)
            {
                return;
            }
            var texels = rawTex.NonCompressedData;


            var image = new Bitmap(rawTex.Width, rawTex.Height, PixelFormat.Format32bppArgb);

            var        bounds = new Rectangle(0, 0, rawTex.Width, rawTex.Height);
            BitmapData bmpData;

            try
            {
                bmpData = image.LockBits(bounds, ImageLockMode.WriteOnly, image.PixelFormat);
                // ignore exceptions thrown by LockBits - we just can't read the image in this case
            }
            catch
            {
                return;
            }

            var ptr = bmpData.Scan0;

            Debug.Assert(bmpData.Stride > 0);

            var countBytes = bmpData.Stride * image.Height;
            var tempBuffer = new byte[countBytes];

            var dataLineLength = image.Width * 4;
            var padding        = bmpData.Stride - dataLineLength;

            Debug.Assert(padding >= 0);

            var n = 0;

            foreach (var texel in texels)
            {
                tempBuffer[n++] = texel.B;
                tempBuffer[n++] = texel.G;
                tempBuffer[n++] = texel.R;
                tempBuffer[n++] = texel.A;

                if (n % dataLineLength == 0)
                {
                    n += padding;
                }
            }

            Marshal.Copy(tempBuffer, 0, ptr, countBytes);
            image.UnlockBits(bmpData);

            _image  = image;
            _result = LoadResult.Good;
        }
Example #14
0
        protected Texture getTexture(string filepath)
        {
            Texture t = null;

            if (filepath[0] == '*') //this is an embedded texture
            {
                string textureIndexStr = filepath.TrimStart('*');
                int    index           = Convert.ToInt32(textureIndexStr);
                if (index >= myScene.TextureCount)
                {
                    Warn.print("texture index({0}) is out of range({1})", index, myScene.TextureCount);
                    return(null);
                }

                EmbeddedTexture texData = myScene.Textures[index];
                if (texData != null)
                {
                    if (texData.IsCompressed)
                    {
                        byte[] bytes = texData.CompressedData;
                        switch (texData.CompressedFormatHint)
                        {
                        case "png": //fallthrough
                        case "jpg":
                            t = new Texture();
                            Stream stream = new MemoryStream(texData.CompressedData, false);
                            t.loadFromStream(stream);
                            break;

                        case "dds":
                            Warn.print("DDS files not supported yet");
                            break;

                        default:
                            Warn.print("Unkown compressed file format {0}", texData.CompressedFormatHint);
                            break;
                        }
                    }
                    else
                    {
                        byte[] bytes = new byte[texData.Width * texData.Height * 4];
                        for (int i = 0; i < texData.Height; i++)
                        {
                            for (int j = 0; i < texData.Width; i++)
                            {
                                bytes[j + (i * texData.Width) + 0] = texData.NonCompressedData[j + (i * texData.Width)].R;
                                bytes[j + (i * texData.Width) + 1] = texData.NonCompressedData[j + (i * texData.Width)].G;
                                bytes[j + (i * texData.Width) + 2] = texData.NonCompressedData[j + (i * texData.Width)].B;
                                bytes[j + (i * texData.Width) + 3] = texData.NonCompressedData[j + (i * texData.Width)].A;
                            }
                        }

                        Texture.PixelData pData = new Texture.PixelData();
                        pData.data        = bytes;
                        pData.dataType    = PixelType.Byte;
                        pData.pixelFormat = PixelFormat.Rgba;
                        t = new Texture(texData.Width, texData.Height, PixelInternalFormat.Rgba8, pData, true);
                    }
                }
            }
            else //just a path name
            {
                string            textureName = filepath.TrimStart('/');
                TextureDescriptor td          = new TextureDescriptor(Path.Combine(myRootPath, textureName), true);
                t = myResourceManager.getResource(td) as Texture;

                if (t == null)
                {
                    Warn.print("Failed to load texture {0}", filepath);
                }
            }

            return(t);
        }
Example #15
0
        public EmbeddedTextureLoader(EmbeddedTexture tex) 
        {
            if(tex.IsCompressed)
            {
                var compTex = tex;
                if(!compTex.HasCompressedData)
                {
                    return;
                }

                // note: have to keep the stream open for the lifetime of the image, so don't Dispose()
                SetFromStream(new MemoryStream(compTex.CompressedData));
                return;
            }

            var rawTex = tex;
            if (!rawTex.HasNonCompressedData || rawTex.Width < 1 || rawTex.Height < 1)
            {
                return;
            }
            var texels = rawTex.NonCompressedData;

            
            var image = new Bitmap(rawTex.Width, rawTex.Height, PixelFormat.Format32bppArgb);

            var bounds = new Rectangle(0, 0, rawTex.Width, rawTex.Height);
            BitmapData bmpData;

            try
            {
                bmpData = image.LockBits(bounds, ImageLockMode.WriteOnly, image.PixelFormat);
                // ignore exceptions thrown by LockBits - we just can't read the image in this case
            }
            catch
            {
                return;
            }

            var ptr = bmpData.Scan0;

            Debug.Assert(bmpData.Stride > 0);

            var countBytes = bmpData.Stride*image.Height;
            var tempBuffer = new byte[countBytes];

            var dataLineLength = image.Width*4;
            var padding = bmpData.Stride - dataLineLength;
            Debug.Assert(padding >= 0);

            var n = 0;
            foreach(var texel in texels)
            {
                tempBuffer[n++] = texel.B;
                tempBuffer[n++] = texel.G;
                tempBuffer[n++] = texel.R;
                tempBuffer[n++] = texel.A;

                if(n % dataLineLength == 0)
                {
                    n += padding;
                }
            }

            Marshal.Copy(tempBuffer, 0, ptr, countBytes);
            image.UnlockBits(bmpData);

            _image = image;
            _result = LoadResult.Good;
        }
Example #16
0
        private SEAObject AppendTexture(EmbeddedTexture texture)
        {
            int sIndex = GetIndexByTag(texture);
            if (sIndex != -1) return (SEATexture)Writer.Objects[sIndex];

            SEATexture tex = new SEATexture(GetValidString(textures, "EmbeddedTexture"), texture.CompressedFormatHint.ToLower());
            tex.Data.WriteBytes(texture.CompressedData);
            tex.tag = texture;

            textures.Add(tex);
            Writer.AddObject(tex);

            return tex;
        }
Example #17
0
 //Maybe create key for textures loaded with assimp and then use them as cache name
 /// <summary>
 /// Converts an Assimp Texture into a Engine/OpenGL Texture
 /// </summary>
 /// <param name="tex">Assimp texture</param>
 /// <returns>GL Texure</returns>
 public static Texture AssimpEmbeddedToTexture(EmbeddedTexture tex)
 {
     return(BytesToTexture(flattenImageData(tex.NonCompressedData), tex.Width, tex.Height));
 }