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); } }
/// <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))); }
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); }
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); }
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); }
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; } }
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; }
public TextureNode(EmbeddedTexture texture) { _texture = texture; }
//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; }
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); }
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; }
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; }
//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)); }