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 Bitmap _loadTexture(ITexmap texMap) { IBitmapTex texture = _getBitmapTex(texMap); if (texture == null) { return(null); } return(TextureUtilities.LoadTexture(texture.Map.FullFilePath, this)); }
private Bitmap _loadTexture(ITexmap texMap) { IBitmapTex texture = _getBitmapTex(texMap); if (texture == null) { return(null); } return(LoadTexture(texture.Map.FullFilePath)); }
private string getSourcePath(ITexmap texMap) { IBitmapTex bitmapTex = _getBitmapTex(texMap); if (bitmapTex != null) { return(bitmapTex.Map.FullFilePath); } else { return(null); } }
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 IStdUVGen _exportUV(IBitmapTex texture, BabylonTexture babylonTexture) { var uvGen = texture.UVGen; 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(texture.MapName).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 getMaterials(ref int geoIndex) { if (ReadUInt32() != (uint)secIDs.MATERIAL_LIST) { datIndex -= 4; return; } //get number of materials datIndex += 20; int matCount = ReadInt32(); //skip trash FFFF data (one for each material) datIndex += matCount * 4; mtlList[geoIndex] = (IMultiMtl)ip.CreateInstance(SClass_ID.Material, global.Class_ID.Create((uint)BuiltInClassIDA.MULTI_CLASS_ID, 0)); mtlList[geoIndex].SetNumSubMtls(matCount); //read material data for (int i = 0; i < matCount; ++i) { IMtl leMat = (IMtl)ip.CreateInstance(SClass_ID.Material, global.Class_ID.Create((uint)custClassIDs.GTAMAT_A, (uint)custClassIDs.GTAMAT_B)); //skip material header, struct header and integer datIndex += 28; //read color leMat.GetParamBlock(0).SetValue(3, 0, global.Color.Create(data[datIndex] / 255.0f, data[datIndex + 1] / 255.0f, data[datIndex + 2] / 255.0f), 0); leMat.GetParamBlock(0).SetValue(6, 0, (int)data[datIndex + 3], 0); //increment and skip unknown datIndex += 8; uint numTextures = ReadUInt32(); //ambient, diffuse and specular? leMat.GetParamBlock(0).SetValue(0, 0, ReadSingle(), 0); leMat.GetParamBlock(0).SetValue(1, 0, ReadSingle(), 0); leMat.GetParamBlock(0).SetValue(2, 0, ReadSingle(), 0); mtlList[geoIndex].SetSubMtl(i, leMat); //read textures for (int ind = 0; ind < numTextures; ++ind) { //skip texture and struct header datIndex += 24; int filtAddr = datIndex; datIndex += 4; //skip three bytes (used later)+1 unknown. //read diffuse texture name datIndex += 4; //skip header int size = ReadInt32(); datIndex += 4; //skip RW version IBitmapTex diffTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0)); diffTex.Name = ReadString(ref size); //read alpha texture name datIndex += 4; //skip header size = ReadInt32(); datIndex += 4; //skip RW version IBitmapTex alphaTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0)); alphaTex.Name = ReadString(ref size); //set tiling and mirror data from filter flags switch (data[filtAddr]) { case 1: diffTex.FilterType = 2; //FILTER_NADA alphaTex.FilterType = 2; break; case 2: diffTex.FilterType = 1; //FILTER_SAT alphaTex.FilterType = 1; //FILTER_SAT break; default: diffTex.FilterType = 0; //FILTER_PYR alphaTex.FilterType = 0; //FILTER_PYR break; } diffTex.UVGen.SetFlag(1 << 2, ~(data[filtAddr + 1] | 0xfffffffe)); diffTex.UVGen.SetFlag(1 << 0, ~(data[filtAddr + 1] | 0xfffffffd)); diffTex.UVGen.SetFlag(1 << 3, ~(data[filtAddr + 1] | 0xffffffef)); diffTex.UVGen.SetFlag(1 << 1, ~(data[filtAddr + 1] | 0xffffffdf)); alphaTex.UVGen.SetFlag(1 << 2, ~(data[filtAddr + 1] | 0xfffffffe)); alphaTex.UVGen.SetFlag(1 << 0, ~(data[filtAddr + 1] | 0xfffffffd)); alphaTex.UVGen.SetFlag(1 << 3, ~(data[filtAddr + 1] | 0xffffffef)); alphaTex.UVGen.SetFlag(1 << 1, ~(data[filtAddr + 1] | 0xffffffdf)); leMat.GetParamBlock(0).SetValue(4, 0, diffTex, 0); leMat.GetParamBlock(0).SetValue(7, 0, alphaTex, 0); leMat.GetParamBlock(0).SetValue(8, 0, 0, 0); //skip extension if (ReadUInt32() == (uint)secIDs.EXTENSION) { int temp = ReadInt32(); datIndex += temp + 4; } else { datIndex -= 4; } } //read material effects if (ReadUInt32() == (uint)secIDs.EXTENSION) { datIndex += 8; //skip section size and RW version //check for material effects, reflection and specular material for (int ind = 0; ind < 3; ++ind) { switch (ReadUInt32()) { case (uint)secIDs.MATERIAL_EFFECTS_PLG: { datIndex += 16; //skip section size, RW version and starting ints (both 2) leMat.GetParamBlock(0).SetValue(9, 0, 100.0f * ReadSingle(), 0); //reflection leMat.GetParamBlock(0).SetValue(11, 0, 1, 0); datIndex += 8; //skip unknown (= 0), skip texture ON/OFF switch 0/1 if (ReadUInt32() == (uint)secIDs.TEXTURE) { //skip texture and struct header datIndex += 20; int filtAddr = datIndex; datIndex += 4; //skip 3 filtering bytes + unkown //read diffuse texture name datIndex += 4; //skip header int size = ReadInt32(); datIndex += 4; //skip RW version IBitmapTex diffTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0)); diffTex.Name = ReadString(ref size); //skip alpha texture if (ReadUInt32() == 0x02) { int temp = ReadInt32(); datIndex += temp + 4; } else { datIndex -= 4; } //set tiling and mirror data from filter flags switch (data[filtAddr]) { case 1: diffTex.FilterType = 2; //FILTER_NADA break; case 2: diffTex.FilterType = 1; //FILTER_SAT break; default: diffTex.FilterType = 0; //FILTER_PYR break; } diffTex.UVGen.SetFlag(1 << 2, ~(data[filtAddr + 1] | 0xfffffffe)); diffTex.UVGen.SetFlag(1 << 0, ~(data[filtAddr + 1] | 0xfffffffd)); diffTex.UVGen.SetFlag(1 << 3, ~(data[filtAddr + 1] | 0xffffffef)); diffTex.UVGen.SetFlag(1 << 1, ~(data[filtAddr + 1] | 0xffffffdf)); leMat.GetParamBlock(0).SetValue(10, 0, diffTex, 0); datIndex += 16; //for some reason zero size extension contains data 00 00 00 00 } } break; case (uint)secIDs.REFLECTION_MATERIAL: { datIndex += 8; leMat.GetParamBlock(0).SetValue(12, 0, global.Color.Create(ReadSingle(), ReadSingle(), ReadSingle()), 0); leMat.GetParamBlock(0).SetValue(15, 0, 255.0f * ReadSingle(), 0); leMat.GetParamBlock(0).SetValue(17, 0, ReadSingle(), 0); datIndex += 4; //skip unknown } break; case (uint)secIDs.SPECULAR_MATERIAL: { int secSize = ReadInt32() - 4; //section size-4 because the float read in ReadSingle() takes up 4 bytes datIndex += 4; leMat.GetParamBlock(0).SetValue(16, 0, 255.0f * ReadSingle(), 0); IBitmapTex diffTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0)); diffTex.Name = ReadString(ref secSize); //-4 because the float read in ReadSingle() takes up 4 bytes //MessageBox.Show(diffTex.Name); //MessageBox.Show(datIndex.ToString()); leMat.GetParamBlock(0).SetValue(13, 0, diffTex, 0); } break; default: datIndex -= 4; break; } } } else { datIndex -= 4; } } // skip extension if (ReadUInt32() == (uint)secIDs.EXTENSION) { int temp = ReadInt32(); datIndex += temp + 4; } else { datIndex -= 4; } }