/// <summary> /// Export the texture using the parameters of babylonTexture except its name. /// Write the bitmap file /// </summary> /// <param name="babylonTexture"></param> /// <param name="bitmap"></param> /// <param name="name"></param> /// <param name="gltf"></param> /// <returns></returns> private GLTFTextureInfo ExportBitmapTexture(GLTF gltf, BabylonTexture babylonTexture, Bitmap bitmap = null, string name = null) { if (babylonTexture != null) { if (bitmap == null) { bitmap = babylonTexture.bitmap; } if (name == null) { name = babylonTexture.name; } } return(ExportTexture(babylonTexture, gltf, name, () => { var extension = Path.GetExtension(name); // Write image to output if (CopyTexturesToOutput) { var absolutePath = Path.Combine(gltf.OutputFolder, name); var imageFormat = extension == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png; RaiseMessage($"GLTFExporter.Texture | write image '{name}' to '{absolutePath}'", 3); bitmap.Save(absolutePath, imageFormat); } return extension.Substring(1); // remove the dot })); }
void AttachMirrorPlane(BabylonTexture babylonTexture, NovaObject novaObject) { // Mirror plane int f1, f2, f3; if (novaObject.Is32bits) { f1 = novaObject.Indices32[2]; f2 = novaObject.Indices32[1]; f3 = novaObject.Indices32[0]; } else { f1 = novaObject.Indices[2]; f2 = novaObject.Indices[1]; f3 = novaObject.Indices[0]; } Vector3 a = novaObject.PositionOnlyVertices[f1]; Vector3 b = novaObject.PositionOnlyVertices[f2]; Vector3 c = novaObject.PositionOnlyVertices[f3]; var mainPlane = new Plane(a, b, c); Matrix matrix = Matrix.Invert(novaObject.WorldMatrix); matrix = Matrix.Transpose(matrix); Plane plane = Plane.Transform(mainPlane, matrix); babylonTexture.mirrorPlane = new[] { plane.Normal.X, plane.Normal.Y, plane.Normal.Z, plane.D }; }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf) { return(ExportTexture(babylonTexture, gltf, null, () => { var sourcePath = babylonTexture.originalPath; if (sourcePath == null || sourcePath == "") { RaiseWarning("Texture path is missing.", 3); return null; } var validImageFormat = GetGltfValidImageFormat(Path.GetExtension(sourcePath)); if (validImageFormat == null) { // Image format is not supported by the exporter RaiseWarning(string.Format("Format of texture {0} is not supported by the exporter. Consider using a standard image format like jpg or png.", Path.GetFileName(sourcePath)), 3); return null; } // Copy texture to output var destPath = Path.Combine(gltf.OutputFolder, babylonTexture.name); destPath = Path.ChangeExtension(destPath, validImageFormat); CopyGltfTexture(sourcePath, destPath); return validImageFormat; })); }
private IStdUVGen _exportUV(IStdUVGen uvGen, BabylonTexture babylonTexture) { switch (uvGen.GetCoordMapping(0)) { case 1: //MAP_SPHERICAL babylonTexture.coordinatesMode = 1; break; case 2: //MAP_PLANAR babylonTexture.coordinatesMode = 2; break; default: babylonTexture.coordinatesMode = 0; break; } babylonTexture.coordinatesIndex = uvGen.MapChannel - 1; if (uvGen.MapChannel > 2) { RaiseWarning(string.Format("Unsupported map channel, Only channel 1 and 2 are supported."), 2); } babylonTexture.uOffset = uvGen.GetUOffs(0); babylonTexture.vOffset = uvGen.GetVOffs(0); babylonTexture.uScale = uvGen.GetUScl(0); babylonTexture.vScale = uvGen.GetVScl(0); if (Path.GetExtension(babylonTexture.name).ToLower() == ".dds") { babylonTexture.vScale *= -1; // Need to invert Y-axis for DDS texture } babylonTexture.uAng = uvGen.GetUAng(0); babylonTexture.vAng = uvGen.GetVAng(0); babylonTexture.wAng = uvGen.GetWAng(0); babylonTexture.wrapU = BabylonTexture.AddressMode.CLAMP_ADDRESSMODE; // CLAMP if ((uvGen.TextureTiling & 1) != 0) // WRAP { babylonTexture.wrapU = BabylonTexture.AddressMode.WRAP_ADDRESSMODE; } else if ((uvGen.TextureTiling & 4) != 0) // MIRROR { babylonTexture.wrapU = BabylonTexture.AddressMode.MIRROR_ADDRESSMODE; } babylonTexture.wrapV = BabylonTexture.AddressMode.CLAMP_ADDRESSMODE; // CLAMP if ((uvGen.TextureTiling & 2) != 0) // WRAP { babylonTexture.wrapV = BabylonTexture.AddressMode.WRAP_ADDRESSMODE; } else if ((uvGen.TextureTiling & 8) != 0) // MIRROR { babylonTexture.wrapV = BabylonTexture.AddressMode.MIRROR_ADDRESSMODE; } return(uvGen); }
private void _exportIsCube(string absolutePath, BabylonTexture babylonTexture, bool allowCube) { if (Path.GetExtension(absolutePath).ToLower() != ".dds") { babylonTexture.isCube = false; } else { try { if (File.Exists(absolutePath)) { babylonTexture.isCube = _isTextureCube(absolutePath); } else { RaiseWarning(string.Format("Texture {0} not found.", absolutePath), 3); } } catch { // silently fails } if (babylonTexture.isCube && !allowCube) { RaiseWarning(string.Format("Cube texture are only supported for reflection channel"), 3); } } }
/// <summary> /// Export the texture using the parameters of babylonTexture except its name. /// Write the bitmap file /// </summary> /// <param name="babylonTexture"></param> /// <param name="bitmap"></param> /// <param name="name"></param> /// <param name="gltf"></param> /// <returns></returns> private GLTFTextureInfo ExportBitmapTexture(GLTF gltf, BabylonTexture babylonTexture, Bitmap bitmap = null, string name = null) { if (babylonTexture != null) { if (bitmap == null) { bitmap = babylonTexture.bitmap; } if (name == null) { name = babylonTexture.name; } } return(ExportTexture(babylonTexture, gltf, name, () => { var extension = Path.GetExtension(name).ToLower(); // Write image to output if (exportParameters.writeTextures) { var absolutePath = Path.Combine(gltf.OutputFolder, name); var imageFormat = extension == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png; logger.RaiseMessage($"GLTFExporter.Texture | write image '{name}' to '{absolutePath}'", 3); TextureUtilities.SaveBitmap(bitmap, absolutePath, imageFormat, exportParameters.txtQuality, logger); } return extension.Substring(1); // remove the dot })); }
private void _exportIsCube(IBitmapTex texture, BabylonTexture babylonTexture, bool allowCube) { var absolutePath = texture.Map.FullFilePath; try { if (File.Exists(absolutePath)) { babylonTexture.isCube = _isTextureCube(absolutePath); } else { RaiseWarning(string.Format("Texture {0} not found.", babylonTexture.name), 2); } } catch { // silently fails } if (babylonTexture.isCube && !allowCube) { RaiseWarning(string.Format("Cube texture are only supported for reflection channel"), 2); } }
private void CopyTextureCube(string texturePath, Cubemap cubemap, BabylonTexture babylonTexture) { if (!babylonScene.AddTextureCube(texturePath)) { return; } try { foreach (CubemapFace face in Enum.GetValues(typeof(CubemapFace))) { var faceTexturePath = Path.Combine(babylonScene.OutputPath, Path.GetFileNameWithoutExtension(texturePath)); switch (face) { case CubemapFace.PositiveX: faceTexturePath += "_px.jpg"; break; case CubemapFace.NegativeX: faceTexturePath += "_nx.jpg"; break; case CubemapFace.PositiveY: faceTexturePath += "_py.jpg"; break; case CubemapFace.NegativeY: faceTexturePath += "_ny.jpg"; break; case CubemapFace.PositiveZ: faceTexturePath += "_pz.jpg"; break; case CubemapFace.NegativeZ: faceTexturePath += "_nz.jpg"; break; } var tempTexture = new Texture2D(cubemap.width, cubemap.height, cubemap.format, false); tempTexture.SetPixels(cubemap.GetPixels(face)); tempTexture.Apply(); File.WriteAllBytes(faceTexturePath, tempTexture.EncodeToJPG()); } } catch (Exception ex) { Debug.LogException(ex); } var textureName = Path.GetFileNameWithoutExtension(texturePath); babylonTexture.name = textureName; babylonTexture.isCube = true; babylonTexture.level = exportationOptions.ReflectionDefaultLevel; babylonTexture.coordinatesMode = 3; }
private void DumpCubeTexture(NovaTexture texture, BabylonTexture babylonTexture, BabylonScene babylonScene) { var textureFilename = Path.Combine(texture.LoadedTexture.Directory, texture.LoadedTexture.Filename); var baseName = Path.GetFileNameWithoutExtension(texture.LoadedTexture.Filename); babylonTexture.isCube = true; babylonTexture.name = baseName; baseName = Path.Combine(babylonScene.OutputPath, baseName); if (!File.Exists(textureFilename)) { texture.LoadedTexture.SaveToDDS(false, textureFilename); } if (!alreadyExportedTextures.Contains(textureFilename)) { alreadyExportedTextures.Add(textureFilename); // Use SharpDX to extract face images var form = new Form { ClientSize = new Size(64, 64) }; var device = new Device(new Direct3D(), 0, DeviceType.Hardware, form.Handle, CreateFlags.HardwareVertexProcessing, new PresentParameters(form.ClientSize.Width, form.ClientSize.Height)); var cubeTexture = CubeTexture.FromFile(device, textureFilename); using (var surface = cubeTexture.GetCubeMapSurface(CubeMapFace.PositiveX, 0)) { Surface.ToFile(surface, baseName + "_px.jpg", ImageFileFormat.Jpg); } using (var surface = cubeTexture.GetCubeMapSurface(CubeMapFace.PositiveY, 0)) { Surface.ToFile(surface, baseName + "_py.jpg", ImageFileFormat.Jpg); } using (var surface = cubeTexture.GetCubeMapSurface(CubeMapFace.PositiveZ, 0)) { Surface.ToFile(surface, baseName + "_pz.jpg", ImageFileFormat.Jpg); } using (var surface = cubeTexture.GetCubeMapSurface(CubeMapFace.NegativeX, 0)) { Surface.ToFile(surface, baseName + "_nx.jpg", ImageFileFormat.Jpg); } using (var surface = cubeTexture.GetCubeMapSurface(CubeMapFace.NegativeY, 0)) { Surface.ToFile(surface, baseName + "_ny.jpg", ImageFileFormat.Jpg); } using (var surface = cubeTexture.GetCubeMapSurface(CubeMapFace.NegativeZ, 0)) { Surface.ToFile(surface, baseName + "_nz.jpg", ImageFileFormat.Jpg); } cubeTexture.Dispose(); device.Dispose(); form.Dispose(); } }
internal void RegisterBaseColorAlphaImageName(BabylonTexture texture, string imageName) { var key = new PairBaseColorAlpha(texture); if (!_DicoPairBaseColorAlphaImageName.ContainsKey(key)) { _DicoPairBaseColorAlphaImageName.Add(key, imageName); } }
void DumpTextureAnimation(NovaTexture texture, BabylonTexture babylonTexture) { var animations = new List <BabylonAnimation>(); DumpInterpolator("Texture UOffset", "uOffset", texture.UOffsetInterpolator, texture.ParentScene, animations); DumpInterpolator("Texture VOffset", "vOffset", texture.VOffsetInterpolator, texture.ParentScene, animations); DumpInterpolator("Texture UScale", "uScale", texture.UScaleInterpolator, texture.ParentScene, animations); DumpInterpolator("Texture VScale", "vScale", texture.VScaleInterpolator, texture.ParentScene, animations); babylonTexture.animations = animations.ToArray(); }
private BabylonTexture ExportEnvironmnentTexture(ITexmap texMap, BabylonScene babylonScene) { if (texMap.GetParamBlock(0) == null || texMap.GetParamBlock(0).Owner == null) { RaiseWarning("Failed to export environment texture. Uncheck \"Use Map\" option to fix this warning."); return(null); } var texture = texMap.GetParamBlock(0).Owner as IBitmapTex; if (texture == null) { RaiseWarning("Failed to export environment texture. Uncheck \"Use Map\" option to fix this warning."); return(null); } var sourcePath = texture.Map.FullFilePath; var fileName = Path.GetFileName(sourcePath); // Allow only dds file format if (!fileName.EndsWith(".dds")) { RaiseWarning("Failed to export environment texture: only .dds format is supported. Uncheck \"Use map\" to fix this warning."); return(null); } var babylonTexture = new BabylonTexture { name = fileName }; // Copy texture to output if (isBabylonExported) { var destPath = Path.Combine(babylonScene.OutputPath, babylonTexture.name); if (CopyTexturesToOutput) { try { if (File.Exists(sourcePath)) { File.Copy(sourcePath, destPath, true); } } catch { // silently fails } } } return(babylonTexture); }
void DumpTexture(NovaTexture texture, BabylonTexture babylonTexture, BabylonScene babylonScene) { babylonTexture.level = texture.Level; babylonTexture.hasAlpha = texture.HasAlpha; babylonTexture.coordinatesMode = (int)texture.MapType; if (texture.LoadedTexture.IsCube) { DumpCubeTexture(texture, babylonTexture, babylonScene); return; } babylonTexture.name = texture.Name; babylonTexture.uOffset = texture.UOffset; babylonTexture.vOffset = texture.VOffset; babylonTexture.uScale = texture.UScale; babylonTexture.vScale = texture.VScale; babylonTexture.uAng = texture.UAng; babylonTexture.vAng = texture.VAng; babylonTexture.wAng = texture.WAng; switch (texture.UAddressMode) { case NovaTextureAddress.Wrap: babylonTexture.wrapU = 1; break; case NovaTextureAddress.Mirror: babylonTexture.wrapU = 2; break; case NovaTextureAddress.Clamp: babylonTexture.wrapU = 0; break; } switch (texture.VAddressMode) { case NovaTextureAddress.Wrap: babylonTexture.wrapV = 1; break; case NovaTextureAddress.Mirror: babylonTexture.wrapV = 2; break; case NovaTextureAddress.Clamp: babylonTexture.wrapV = 0; break; } babylonTexture.coordinatesIndex = texture.MapCoordinateIndex; DumpTextureAnimation(texture, babylonTexture); babylonTexture.name = CopyTexture(texture, babylonScene); }
/// <summary> /// Export the texture using the parameters of babylonTexture except its name. /// Write the bitmap file /// </summary> /// <param name="babylonTexture"></param> /// <param name="bitmap"></param> /// <param name="name"></param> /// <param name="gltf"></param> /// <returns></returns> private GLTFTextureInfo ExportBitmapTexture(BabylonTexture babylonTexture, Bitmap bitmap, string name, GLTF gltf) { // Copy image to output if (CopyTexturesToOutput) { var absolutePath = Path.Combine(gltf.OutputPath, name); RaiseMessage($"GLTFExporter.Texture | write image '{name}' to '{absolutePath}'", 1); bitmap.Save(absolutePath); } return(ExportTexture(babylonTexture, gltf, name)); }
/// <summary> /// Export the texture using the parameters of babylonTexture except its name. /// Write the bitmap file /// </summary> /// <param name="babylonTexture"></param> /// <param name="bitmap"></param> /// <param name="name"></param> /// <param name="gltf"></param> /// <returns></returns> private GLTFTextureInfo ExportBitmapTexture(BabylonTexture babylonTexture, Bitmap bitmap, string name, GLTF gltf) { // Copy image to output if (CopyTexturesToOutput) { var absolutePath = Path.Combine(gltf.OutputFolder, name); var imageFormat = Path.GetExtension(name) == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png; RaiseMessage($"GLTFExporter.Texture | write image '{name}' to '{absolutePath}'", 1); bitmap.Save(absolutePath, imageFormat); } return(ExportTexture(babylonTexture, gltf, name)); }
internal string BaseColorAlphaImageNameLookup(BabylonTexture texture, string defaultName = null) { var key = new PairBaseColorAlpha(texture); string imageName = null; if (_DicoPairBaseColorAlphaImageName.TryGetValue(key, out imageName)) { return(imageName); } key = _DicoPairBaseColorAlphaImageName.Keys.Where(k => k.baseColorPath.Equals(key.baseColorPath)).FirstOrDefault(); return(key != null ? _DicoPairBaseColorAlphaImageName[key] : defaultName); }
private void DumpRenderTargetTexture(NovaTexture texture, BabylonTexture babylonTexture, int renderSize, float level, NovaMirroredObjectsList renderList) { babylonTexture.level = level; babylonTexture.hasAlpha = false; babylonTexture.coordinatesMode = (int)NovaTexture.NovaTextureMapType.Projection; babylonTexture.name = texture.Name; babylonTexture.uOffset = texture.UOffset; babylonTexture.vOffset = texture.VOffset; babylonTexture.uScale = texture.UScale; babylonTexture.vScale = texture.VScale; babylonTexture.uAng = texture.UAng; babylonTexture.vAng = texture.VAng; babylonTexture.wAng = texture.WAng; switch (texture.UAddressMode) { case NovaTextureAddress.Wrap: babylonTexture.wrapU = 1; break; case NovaTextureAddress.Mirror: babylonTexture.wrapU = 2; break; case NovaTextureAddress.Clamp: babylonTexture.wrapU = 0; break; } switch (texture.VAddressMode) { case NovaTextureAddress.Wrap: babylonTexture.wrapV = 1; break; case NovaTextureAddress.Mirror: babylonTexture.wrapV = 2; break; case NovaTextureAddress.Clamp: babylonTexture.wrapV = 0; break; } babylonTexture.coordinatesIndex = texture.MapCoordinateIndex; DumpTextureAnimation(texture, babylonTexture); babylonTexture.isRenderTarget = true; babylonTexture.renderTargetSize = renderSize; babylonTexture.renderList = renderList.Select(o => o.ID.ToString()).ToArray(); }
/// <summary> /// Export the texture using the parameters of babylonTexture except its name. /// Write the bitmap file /// </summary> /// <param name="babylonTexture"></param> /// <param name="bitmap"></param> /// <param name="name"></param> /// <param name="gltf"></param> /// <returns></returns> private GLTFTextureInfo ExportBitmapTexture(GLTF gltf, BabylonTexture babylonTexture, Bitmap bitmap = null, string name = null) { if (babylonTexture != null) { if (bitmap == null) { bitmap = babylonTexture.bitmap; } if (name == null) { name = babylonTexture.name; } } return(ExportTexture(babylonTexture, gltf, name)); }
private void ConvertUnitySkyboxToBabylon(Camera camera, float progress) { // Skybox if ((camera.clearFlags & CameraClearFlags.Skybox) == CameraClearFlags.Skybox) { if (RenderSettings.skybox != null) { if (RenderSettings.skybox.shader.name == "Skybox/Cubemap") { var cubeMap = RenderSettings.skybox.GetTexture("_Tex") as Cubemap; if (cubeMap != null) { var skytex = new BabylonTexture(); CopyTextureCube("sceneSkybox.hdr", cubeMap, skytex); skytex.coordinatesMode = 5; skytex.level = RenderSettings.reflectionIntensity; BabylonMesh skybox = new BabylonMesh(); skybox.indices = new[] { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23 }; skybox.positions = new[] { 50.0f, -50.0f, 50.0f, -50.0f, -50.0f, 50.0f, -50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, -50.0f, -50.0f, 50.0f, -50.0f, -50.0f, -50.0f, -50.0f, 50.0f, -50.0f, -50.0f, 50.0f, 50.0f, -50.0f, 50.0f, -50.0f, -50.0f, 50.0f, -50.0f, 50.0f, 50.0f, 50.0f, 50.0f, -50.0f, 50.0f, 50.0f, -50.0f, -50.0f, 50.0f, -50.0f, -50.0f, -50.0f, -50.0f, 50.0f, -50.0f, -50.0f, 50.0f, 50.0f, -50.0f, 50.0f, -50.0f, 50.0f, 50.0f, -50.0f, 50.0f, 50.0f, 50.0f, 50.0f, -50.0f, 50.0f, 50.0f, -50.0f, -50.0f, -50.0f, -50.0f, -50.0f, -50.0f, -50.0f, 50.0f }; skybox.uvs = new[] { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; skybox.normals = new[] { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0, 0f }; var skyboxMaterial = new BabylonPBRMaterial() { name = "sceneSkyboxMaterial", id = Guid.NewGuid().ToString(), albedo = new[] { 1.0f, 1.0f, 1.0f, 1.0f }, reflectivity = new[] { 0.0f, 0.0f, 0.0f }, microSurface = 1.0f, directIntensity = 0.0f, specularIntensity = 0.0f, environmentIntensity = 1.0f }; skyboxMaterial.backFaceCulling = false; skybox.materialId = skyboxMaterial.id; skybox.infiniteDistance = true; skyboxMaterial.reflectionTexture = skytex; babylonScene.MeshesList.Add(skybox); babylonScene.MaterialsList.Add(skyboxMaterial); babylonScene.AddTextureCube("sceneSkyboxMaterial"); } } } } }
private BabylonTexture ExportEnvironmnentTexture(ITexmap texMap, BabylonScene babylonScene) { if (texMap.GetParamBlock(0) == null || texMap.GetParamBlock(0).Owner == null) { return(null); } var texture = texMap.GetParamBlock(0).Owner as IBitmapTex; if (texture == null) { return(null); } var sourcePath = texture.Map.FullFilePath; var babylonTexture = new BabylonTexture { name = Path.GetFileName(sourcePath) }; // Copy texture to output if (isBabylonExported) { var destPath = Path.Combine(babylonScene.OutputPath, babylonTexture.name); if (CopyTexturesToOutput) { try { if (File.Exists(sourcePath)) { File.Copy(sourcePath, destPath, true); } } catch { // silently fails } } } return(babylonTexture); }
private BabylonFurMaterial ExportFurModifier(IModifier modifier, String sourceMeshName, BabylonScene babylonScene) { RaiseMessage("Export Fur Modifier", 2); var paramBlock = modifier.GetParamBlock(0); // 3dsMax "Cut Length" is in percentages - "100%" will be "20" babylon spacing // (babylon Fur length means the distance from the obj, while the length of the hair is the spacing) var cutLength = paramBlock.GetFloat(CUT_LENGTH_PARAM_ID, 0, 0); var spacing = (int)Math.Round(cutLength / 5); // 3dsMax "Root Thick" is in percentages - "100%" will be "1" babylon density // (lower density in babylon is thicker hair - lower root thick in 3dsMax is thinner) var rootThickness = paramBlock.GetFloat(ROOT_THICKNESS_PARAM_ID, 0, 0); var density = (int)Math.Ceiling((100.1f - rootThickness) / 5); var rootColor = paramBlock.GetColor(ROOT_COLOR_PARAM_ID, 0, 0); var furColor = new float[] { rootColor.R, rootColor.G, rootColor.B }; if (paramBlock.GetTexmap(MAPS_PARAM_ID, 0, 11) != null) { RaiseWarning("Tip texture is not supported. Use root texture instead", 2); } BabylonTexture diffuseTexture = null; ITexmap rootColorTexmap = paramBlock.GetTexmap(MAPS_PARAM_ID, 0, 14); if (rootColorTexmap != null) { diffuseTexture = ExportTexture(rootColorTexmap, 0f, babylonScene); diffuseTexture.level = 1; } return(new BabylonFurMaterial { id = modifier.GetGuid().ToString(), name = modifier.GetGuid().ToString(), sourceMeshName = sourceMeshName, furDensity = density, furSpacing = spacing, diffuseTexture = diffuseTexture, furColor = furColor, }); }
private BabylonTexture DumpTexture(Texture texture, Material material = null, string name = "", bool isLightmap = false) { if (texture == null) { return(null); } var texturePath = AssetDatabase.GetAssetPath(texture); var textureName = Path.GetFileName(texturePath); var babylonTexture = new BabylonTexture { name = textureName }; if (material != null) { var textureScale = material.GetTextureScale(name); babylonTexture.uScale = textureScale.x; babylonTexture.vScale = textureScale.y; var textureOffset = material.GetTextureOffset(name); babylonTexture.uOffset = textureOffset.x; babylonTexture.vOffset = textureOffset.y; } var texture2D = texture as Texture2D; if (texture2D) { babylonTexture.hasAlpha = texture2D.alphaIsTransparency; CopyTexture(texturePath, texture2D, babylonTexture, isLightmap); } else { var cubemap = texture as Cubemap; if (cubemap != null) { CopyTextureCube(texturePath, cubemap, babylonTexture); } } return(babylonTexture); }
private BabylonTexture DumpReflectionTexture() { if (sceneReflectionTexture != null) { return(sceneReflectionTexture); } // Take only reflection source currently and not the RenderSettings.ambientMode if (RenderSettings.defaultReflectionMode == UnityEngine.Rendering.DefaultReflectionMode.Skybox) { var skybox = RenderSettings.skybox; if (skybox != null) { if (skybox.shader.name == "Skybox/Cubemap") { var cubeMap = skybox.GetTexture("_Tex") as Cubemap; if (cubeMap != null) { sceneReflectionTexture = new BabylonTexture(); CopyTextureCube("sceneReflectionTexture.hdr", cubeMap, sceneReflectionTexture); sceneReflectionTexture.level = RenderSettings.reflectionIntensity; } } //else if (skybox.shader.name == "Skybox/6 Sided") //{ // // TODO. HDR faces. //} } } else if (RenderSettings.customReflection != null) { var cubeMap = RenderSettings.customReflection; sceneReflectionTexture = new BabylonTexture(); CopyTextureCube("sceneReflectionTexture.hdr", cubeMap, sceneReflectionTexture); sceneReflectionTexture.level = RenderSettings.reflectionIntensity; } return(sceneReflectionTexture); }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf, string name, Func <string> writeImageFunc) { if (babylonTexture == null) { return(null); } if (name == null) { name = babylonTexture.name; } logger.RaiseMessage("GLTFExporter.Texture | Export texture named: " + name, 2); if (glTFTextureInfoMap.ContainsKey(babylonTexture.Id)) { return(glTFTextureInfoMap[babylonTexture.Id]); } else { string validImageFormat = writeImageFunc.Invoke(); if (validImageFormat == null) { return(null); } name = Path.ChangeExtension(name, validImageFormat); // -------------------------- // -------- Sampler --------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create sampler", 3); GLTFSampler gltfSampler = new GLTFSampler(); gltfSampler.index = gltf.SamplersList.Count; // --- Retrieve info from babylon texture --- // Mag and min filters GLTFSampler.TextureMagFilter?magFilter; GLTFSampler.TextureMinFilter?minFilter; getSamplingParameters(babylonTexture.samplingMode, out magFilter, out minFilter); gltfSampler.magFilter = magFilter; gltfSampler.minFilter = minFilter; // WrapS and wrapT gltfSampler.wrapS = getWrapMode(babylonTexture.wrapU); gltfSampler.wrapT = getWrapMode(babylonTexture.wrapV); var matchingSampler = gltf.SamplersList.FirstOrDefault(sampler => sampler.wrapS == gltfSampler.wrapS && sampler.wrapT == gltfSampler.wrapT && sampler.magFilter == gltfSampler.magFilter && sampler.minFilter == gltfSampler.minFilter); if (matchingSampler != null) { gltfSampler = matchingSampler; } else { gltf.SamplersList.Add(gltfSampler); } // -------------------------- // --------- Image ---------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create image", 3); GLTFImage gltfImage = null; if (glTFImageMap.ContainsKey(name)) { gltfImage = glTFImageMap[name]; } else { string textureUri = name; if (!string.IsNullOrWhiteSpace(exportParameters.textureFolder)) { textureUri = PathUtilities.GetRelativePath(exportParameters.outputPath, exportParameters.textureFolder) + "/" + name; } gltfImage = new GLTFImage { uri = textureUri }; gltfImage.index = gltf.ImagesList.Count; gltf.ImagesList.Add(gltfImage); glTFImageMap.Add(name, gltfImage); switch (validImageFormat) { case "jpg": gltfImage.FileExtension = "jpeg"; break; case "png": gltfImage.FileExtension = "png"; break; } } // -------------------------- // -------- Texture --------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create texture", 3); var gltfTexture = new GLTFTexture { name = name, sampler = gltfSampler.index, source = gltfImage.index }; gltfTexture.index = gltf.TexturesList.Count; gltf.TexturesList.Add(gltfTexture); // -------------------------- // ------ TextureInfo ------- // -------------------------- var gltfTextureInfo = new GLTFTextureInfo { index = gltfTexture.index, texCoord = babylonTexture.coordinatesIndex }; if (!(babylonTexture.uOffset == 0) || !(babylonTexture.vOffset == 0) || !(babylonTexture.uScale == 1) || !(babylonTexture.vScale == -1) || !(babylonTexture.wAng == 0)) { // Add texture extension if enabled in the export settings if (exportParameters.enableKHRTextureTransform) { AddTextureTransformExtension(ref gltf, ref gltfTextureInfo, babylonTexture); } else { logger.RaiseWarning("GLTFExporter.Texture | KHR_texture_transform is not enabled, so the texture may look incorrect at runtime!", 3); logger.RaiseWarning("GLTFExporter.Texture | KHR_texture_transform is not enabled, so the texture may look incorrect at runtime!", 3); } } var textureID = name + TextureTransformID(gltfTextureInfo); // Check for texture optimization. This is done here after the texture transform has been potentially applied to the texture extension if (CheckIfImageIsRegistered(textureID)) { var textureComponent = GetRegisteredTexture(textureID); return(textureComponent); } // Add the texture in the dictionary RegisterTexture(gltfTextureInfo, textureID); glTFTextureInfoMap[babylonTexture.Id] = gltfTextureInfo; return(gltfTextureInfo); } }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf) { return(ExportTexture(babylonTexture, gltf, null, () => { return TryWriteImage(gltf, babylonTexture.originalPath, babylonTexture.name); })); }
/// <summary> /// Add the KHR_texture_transform to the glTF file /// </summary> /// <param name="gltf"></param> /// <param name="babylonMaterial"></param> private void AddTextureTransformExtension(ref GLTF gltf, ref GLTFTextureInfo gltfTextureInfo, BabylonTexture babylonTexture) { if (!gltf.extensionsUsed.Contains(KHR_texture_transform)) { gltf.extensionsUsed.Add(KHR_texture_transform); } if (!gltf.extensionsRequired.Contains(KHR_texture_transform)) { gltf.extensionsRequired.Add(KHR_texture_transform); } float angle = babylonTexture.wAng; float angleDirect = -babylonTexture.wAng; KHR_texture_transform textureTransform = new KHR_texture_transform { offset = new float[] { babylonTexture.uOffset, -babylonTexture.vOffset }, rotation = angle, scale = new float[] { babylonTexture.uScale, -babylonTexture.vScale }, texCoord = babylonTexture.coordinatesIndex }; if (gltfTextureInfo.extensions == null) { gltfTextureInfo.extensions = new GLTFExtensions(); } gltfTextureInfo.extensions[KHR_texture_transform] = textureTransform; }
private IStdUVGen _exportUV(IStdUVGen uvGen, BabylonTexture babylonTexture) { switch (uvGen.GetCoordMapping(0)) { case 1: //MAP_SPHERICAL babylonTexture.coordinatesMode = BabylonTexture.CoordinatesMode.SPHERICAL_MODE; break; case 2: //MAP_PLANAR babylonTexture.coordinatesMode = BabylonTexture.CoordinatesMode.PLANAR_MODE; break; default: babylonTexture.coordinatesMode = BabylonTexture.CoordinatesMode.EXPLICIT_MODE; break; } babylonTexture.coordinatesIndex = uvGen.MapChannel - 1; if (uvGen.MapChannel > 2) { RaiseWarning(string.Format("Unsupported map channel, Only channel 1 and 2 are supported."), 3); } babylonTexture.uOffset = uvGen.GetUOffs(0); babylonTexture.vOffset = -uvGen.GetVOffs(0); babylonTexture.uScale = uvGen.GetUScl(0); babylonTexture.vScale = uvGen.GetVScl(0); var offset = new BabylonVector3(babylonTexture.uOffset, -babylonTexture.vOffset, 0); var scale = new BabylonVector3(babylonTexture.uScale, babylonTexture.vScale, 1); var rotationEuler = new BabylonVector3(uvGen.GetUAng(0), uvGen.GetVAng(0), uvGen.GetWAng(0)); var rotation = BabylonQuaternion.FromEulerAngles(rotationEuler.X, rotationEuler.Y, rotationEuler.Z); var pivotCenter = new BabylonVector3(-0.5f, -0.5f, 0); var transformMatrix = MathUtilities.ComputeTextureTransformMatrix(pivotCenter, offset, rotation, scale); transformMatrix.decompose(scale, rotation, offset); var texTransformRotationEuler = rotation.toEulerAngles(); babylonTexture.uOffset = -offset.X; babylonTexture.vOffset = -offset.Y; babylonTexture.uScale = scale.X; babylonTexture.vScale = -scale.Y; babylonTexture.uRotationCenter = 0.0f; babylonTexture.vRotationCenter = 0.0f; babylonTexture.invertY = false; babylonTexture.uAng = texTransformRotationEuler.X; babylonTexture.vAng = texTransformRotationEuler.Y; babylonTexture.wAng = texTransformRotationEuler.Z; if (Path.GetExtension(babylonTexture.name).ToLower() == ".dds") { babylonTexture.vScale *= -1; // Need to invert Y-axis for DDS texture } if (babylonTexture.wAng != 0f && (babylonTexture.uScale != 1f || babylonTexture.vScale != 1f) && (Math.Abs(babylonTexture.uScale) - Math.Abs(babylonTexture.vScale)) > float.Epsilon) { RaiseWarning("Rotation and non-uniform tiling (scale) on a texture is not supported as it will cause texture shearing. You can use the map UV of the mesh for those transformations.", 3); } babylonTexture.wrapU = BabylonTexture.AddressMode.CLAMP_ADDRESSMODE; // CLAMP if ((uvGen.TextureTiling & 1) != 0) // WRAP { babylonTexture.wrapU = BabylonTexture.AddressMode.WRAP_ADDRESSMODE; } else if ((uvGen.TextureTiling & 4) != 0) // MIRROR { babylonTexture.wrapU = BabylonTexture.AddressMode.MIRROR_ADDRESSMODE; } babylonTexture.wrapV = BabylonTexture.AddressMode.CLAMP_ADDRESSMODE; // CLAMP if ((uvGen.TextureTiling & 2) != 0) // WRAP { babylonTexture.wrapV = BabylonTexture.AddressMode.WRAP_ADDRESSMODE; } else if ((uvGen.TextureTiling & 8) != 0) // MIRROR { babylonTexture.wrapV = BabylonTexture.AddressMode.MIRROR_ADDRESSMODE; } return(uvGen); }
private BabylonTexture ExportTexture(ITexmap texMap, BabylonScene babylonScene, float amount = 1.0f, bool allowCube = false, bool forceAlpha = false) { IBitmapTex texture = _getBitmapTex(texMap, false); if (texture == null) { float specialAmount; var specialTexMap = _getSpecialTexmap(texMap, out specialAmount); texture = _getBitmapTex(specialTexMap, false); amount *= specialAmount; } if (texture == null) { return(null); } var sourcePath = texture.Map.FullFilePath; if (sourcePath == null || sourcePath == "") { RaiseWarning("Texture path is missing.", 2); return(null); } RaiseMessage("Export texture named: " + Path.GetFileName(sourcePath), 2); var validImageFormat = TextureUtilities.GetValidImageFormat(Path.GetExtension(sourcePath)); if (validImageFormat == null) { // Image format is not supported by the exporter RaiseWarning(string.Format("Format of texture {0} is not supported by the exporter. Consider using a standard image format like jpg or png.", Path.GetFileName(sourcePath)), 3); return(null); } var textureID = texture.GetGuid().ToString(); if (textureMap.ContainsKey(textureID)) { return(textureMap[textureID]); } else { var babylonTexture = new BabylonTexture(textureID) { name = Path.GetFileNameWithoutExtension(texture.MapName) + "." + validImageFormat }; RaiseMessage($"texture id = {babylonTexture.Id}", 2); // Level babylonTexture.level = amount; // Alpha if (forceAlpha) { babylonTexture.hasAlpha = true; babylonTexture.getAlphaFromRGB = (texture.AlphaSource == 2) || (texture.AlphaSource == 3); // 'RGB intensity' or 'None (Opaque)' } else { babylonTexture.hasAlpha = (texture.AlphaSource != 3); // Not 'None (Opaque)' babylonTexture.getAlphaFromRGB = (texture.AlphaSource == 2); // 'RGB intensity' } // UVs var uvGen = _exportUV(texture.UVGen, babylonTexture); // Animations var animations = new List <BabylonAnimation>(); ExportFloatAnimation("uOffset", animations, key => new[] { uvGen.GetUOffs(key) }); ExportFloatAnimation("vOffset", animations, key => new[] { -uvGen.GetVOffs(key) }); ExportFloatAnimation("uScale", animations, key => new[] { uvGen.GetUScl(key) }); ExportFloatAnimation("vScale", animations, key => new[] { uvGen.GetVScl(key) }); ExportFloatAnimation("uAng", animations, key => new[] { uvGen.GetUAng(key) }); ExportFloatAnimation("vAng", animations, key => new[] { uvGen.GetVAng(key) }); ExportFloatAnimation("wAng", animations, key => new[] { uvGen.GetWAng(key) }); babylonTexture.animations = animations.ToArray(); // Copy texture to output if (isBabylonExported) { var destPath = Path.Combine(babylonScene.OutputPath, babylonTexture.name); TextureUtilities.CopyTexture(sourcePath, destPath, exportParameters.txtQuality, this); // Is cube _exportIsCube(Path.Combine(babylonScene.OutputPath, babylonTexture.name), babylonTexture, allowCube); } else { babylonTexture.isCube = false; } babylonTexture.originalPath = sourcePath; return(babylonTexture); } }
private BabylonTexture ExportSpecularTexture(IIGameMaterial materialNode, float[] specularColor, BabylonScene babylonScene) { ITexmap specularColorTexMap = _getTexMap(materialNode, 2); ITexmap specularLevelTexMap = _getTexMap(materialNode, 3); // --- Babylon texture --- var specularColorTexture = _getBitmapTex(specularColorTexMap); var specularLevelTexture = _getBitmapTex(specularLevelTexMap); if (specularLevelTexture == null) { // Copy specular color image // Assume specular color texture is already pre-multiplied by a global specular level value // So do not use global specular level return(ExportTexture(specularColorTexture, babylonScene)); } // Use one as a reference for UVs parameters var texture = specularColorTexture != null ? specularColorTexture : specularLevelTexture; if (texture == null) { return(null); } RaiseMessage("Multiply specular color and level textures", 2); string nameText = null; nameText = (specularColorTexture != null ? Path.GetFileNameWithoutExtension(specularColorTexture.Map.FullFilePath) : TextureUtilities.ColorToStringName(specularColor)) + Path.GetFileNameWithoutExtension(specularLevelTexture.Map.FullFilePath) + "_specularColor"; var textureID = texture.GetGuid().ToString(); if (textureMap.ContainsKey(textureID)) { return(textureMap[textureID]); } else { var babylonTexture = new BabylonTexture(textureID) { name = nameText + ".jpg" // TODO - unsafe name, may conflict with another texture name }; // Level babylonTexture.level = 1.0f; // UVs var uvGen = _exportUV(texture.UVGen, babylonTexture); // Is cube _exportIsCube(texture.Map.FullFilePath, babylonTexture, false); // --- Multiply specular color and level maps --- // Alpha babylonTexture.hasAlpha = false; babylonTexture.getAlphaFromRGB = false; if (exportParameters.writeTextures) { // Load bitmaps var specularColorBitmap = _loadTexture(specularColorTexMap); var specularLevelBitmap = _loadTexture(specularLevelTexMap); if (specularLevelBitmap == null) { // Copy specular color image RaiseError("Failed to load specular level texture. Specular color is exported alone.", 3); return(ExportTexture(specularColorTexture, babylonScene)); } // Retreive dimensions int width = 0; int height = 0; var haveSameDimensions = TextureUtilities.GetMinimalBitmapDimensions(out width, out height, specularColorBitmap, specularLevelBitmap); if (!haveSameDimensions) { RaiseError("Specular color and specular level maps should have same dimensions", 3); } // Create pre-multiplied specular color map var _specularColor = Color.FromArgb( (int)(specularColor[0] * 255), (int)(specularColor[1] * 255), (int)(specularColor[2] * 255)); Bitmap specularColorPreMultipliedBitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { var specularColorAtPixel = specularColorBitmap != null?specularColorBitmap.GetPixel(x, y) : _specularColor; var specularLevelAtPixel = specularLevelBitmap.GetPixel(x, y); var specularColorPreMultipliedAtPixel = specularColorAtPixel.multiply(specularLevelAtPixel); specularColorPreMultipliedBitmap.SetPixel(x, y, specularColorPreMultipliedAtPixel); } } // Write bitmap if (isBabylonExported) { RaiseMessage($"Texture | write image '{babylonTexture.name}'", 3); TextureUtilities.SaveBitmap(specularColorPreMultipliedBitmap, babylonScene.OutputPath, babylonTexture.name, ImageFormat.Jpeg, exportParameters.txtQuality, this); } else { // Store created bitmap for further use in gltf export babylonTexture.bitmap = specularColorPreMultipliedBitmap; } } textureMap.Add(babylonTexture.Id, babylonTexture); return(babylonTexture); } }
private BabylonTexture ExportORMTexture(ITexmap ambientOcclusionTexMap, ITexmap roughnessTexMap, ITexmap metallicTexMap, float metallic, float roughness, BabylonScene babylonScene, bool invertRoughness) { // --- Babylon texture --- var metallicTexture = _getBitmapTex(metallicTexMap); var roughnessTexture = _getBitmapTex(roughnessTexMap); var ambientOcclusionTexture = _getBitmapTex(ambientOcclusionTexMap); // Use metallic or roughness texture as a reference for UVs parameters var texture = metallicTexture != null ? metallicTexture : roughnessTexture; if (texture == null) { return(null); } RaiseMessage("Export ORM texture", 2); var textureID = texture.GetGuid().ToString(); if (textureMap.ContainsKey(textureID)) { return(textureMap[textureID]); } else { var babylonTexture = new BabylonTexture(textureID) { name = (ambientOcclusionTexMap != null ? Path.GetFileNameWithoutExtension(ambientOcclusionTexture.Map.FileName) : "") + (roughnessTexMap != null ? Path.GetFileNameWithoutExtension(roughnessTexture.Map.FileName) : ("" + (int)(roughness * 255))) + (metallicTexMap != null ? Path.GetFileNameWithoutExtension(metallicTexture.Map.FileName) : ("" + (int)(metallic * 255))) + ".jpg" // TODO - unsafe name, may conflict with another texture name }; // UVs var uvGen = _exportUV(texture.UVGen, babylonTexture); // Is cube _exportIsCube(texture.Map.FullFilePath, babylonTexture, false); // --- Merge metallic and roughness maps --- if (!isTextureOk(metallicTexMap) && !isTextureOk(roughnessTexMap)) { return(null); } if (exportParameters.writeTextures) { // Load bitmaps var metallicBitmap = _loadTexture(metallicTexMap); var roughnessBitmap = _loadTexture(roughnessTexMap); var ambientOcclusionBitmap = _loadTexture(ambientOcclusionTexMap); // Retreive dimensions int width = 0; int height = 0; var haveSameDimensions = TextureUtilities.GetMinimalBitmapDimensions(out width, out height, metallicBitmap, roughnessBitmap, ambientOcclusionBitmap); if (!haveSameDimensions) { RaiseError((ambientOcclusionBitmap != null ? "Occlusion, roughness and metallic " : "Metallic and roughness") + " maps should have same dimensions", 3); } // Create ORM map Bitmap ormBitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int _occlusion = ambientOcclusionBitmap != null?ambientOcclusionBitmap.GetPixel(x, y).R : 0; int _roughness = roughnessBitmap != null ? (invertRoughness ? 255 - roughnessBitmap.GetPixel(x, y).G : roughnessBitmap.GetPixel(x, y).G) : (int)(roughness * 255.0f); int _metallic = metallicBitmap != null?metallicBitmap.GetPixel(x, y).B : (int)(metallic * 255.0f); // The occlusion values are sampled from the R channel. // The roughness values are sampled from the G channel. // The metalness values are sampled from the B channel. Color colorMetallicRoughness = Color.FromArgb(_occlusion, _roughness, _metallic); ormBitmap.SetPixel(x, y, colorMetallicRoughness); } } // Write bitmap if (isBabylonExported) { RaiseMessage($"Texture | write image '{babylonTexture.name}'", 3); TextureUtilities.SaveBitmap(ormBitmap, babylonScene.OutputPath, babylonTexture.name, ImageFormat.Jpeg, exportParameters.txtQuality, this); } else { // Store created bitmap for further use in gltf export babylonTexture.bitmap = ormBitmap; } } textureMap[babylonTexture.Id] = babylonTexture; return(babylonTexture); } }