|
@@ -3,20 +3,8 @@
|
|
|
// Code licensed under the BSD License.
|
|
// Code licensed under the BSD License.
|
|
|
// http://www.anki3d.org/LICENSE
|
|
// http://www.anki3d.org/LICENSE
|
|
|
|
|
|
|
|
-#include "Importer.h"
|
|
|
|
|
-
|
|
|
|
|
-#define STB_IMAGE_IMPLEMENTATION
|
|
|
|
|
-#define STBI_ASSERT(x) ANKI_ASSERT(x)
|
|
|
|
|
-#if ANKI_COMPILER_GCC_COMPATIBLE
|
|
|
|
|
-# pragma GCC diagnostic push
|
|
|
|
|
-# pragma GCC diagnostic ignored "-Wfloat-conversion"
|
|
|
|
|
-# pragma GCC diagnostic ignored "-Wconversion"
|
|
|
|
|
-# pragma GCC diagnostic ignored "-Wtype-limits"
|
|
|
|
|
-#endif
|
|
|
|
|
-#include <stb/stb_image.h>
|
|
|
|
|
-#if ANKI_COMPILER_GCC_COMPATIBLE
|
|
|
|
|
-# pragma GCC diagnostic pop
|
|
|
|
|
-#endif
|
|
|
|
|
|
|
+#include <anki/importer/GltfImporter.h>
|
|
|
|
|
+#include <anki/resource/ImageLoader.h>
|
|
|
|
|
|
|
|
namespace anki
|
|
namespace anki
|
|
|
{
|
|
{
|
|
@@ -52,24 +40,6 @@ const char* MATERIAL_TEMPLATE = R"(<!-- This file is auto generated by ImporterM
|
|
|
</material>
|
|
</material>
|
|
|
)";
|
|
)";
|
|
|
|
|
|
|
|
-static std::string replaceAllString(const std::string& str, const std::string& from, const std::string& to)
|
|
|
|
|
-{
|
|
|
|
|
- if(from.empty())
|
|
|
|
|
- {
|
|
|
|
|
- return str;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- std::string out = str;
|
|
|
|
|
- size_t start_pos = 0;
|
|
|
|
|
- while((start_pos = out.find(from, start_pos)) != std::string::npos)
|
|
|
|
|
- {
|
|
|
|
|
- out.replace(start_pos, from.length(), to);
|
|
|
|
|
- start_pos += to.length();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return out;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
static CString getTextureUri(const cgltf_texture_view& view)
|
|
static CString getTextureUri(const cgltf_texture_view& view)
|
|
|
{
|
|
{
|
|
|
ANKI_ASSERT(view.texture);
|
|
ANKI_ASSERT(view.texture);
|
|
@@ -79,22 +49,22 @@ static CString getTextureUri(const cgltf_texture_view& view)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Read the texture and find out if
|
|
/// Read the texture and find out if
|
|
|
-static Error identifyMetallicRoughnessTexture(CString fname, F32& constantMetalines, F32& constantRoughness)
|
|
|
|
|
|
|
+static Error identifyMetallicRoughnessTexture(
|
|
|
|
|
+ CString fname, F32& constantMetalines, F32& constantRoughness, GenericMemoryPoolAllocator<U8>& alloc)
|
|
|
{
|
|
{
|
|
|
- int width, height, comp;
|
|
|
|
|
- U8Vec4* data = reinterpret_cast<U8Vec4*>(stbi_load(fname.cstr(), &width, &height, &comp, 4));
|
|
|
|
|
- if(!data)
|
|
|
|
|
- {
|
|
|
|
|
- ANKI_GLTF_LOGE("Failed to read: %s", fname.cstr());
|
|
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ImageLoader iloader(alloc);
|
|
|
|
|
+ ANKI_CHECK(iloader.load(fname));
|
|
|
|
|
+ ANKI_ASSERT(iloader.getColorFormat() == ImageLoaderColorFormat::RGBA8);
|
|
|
|
|
+ ANKI_ASSERT(iloader.getCompression() == ImageLoaderDataCompression::RAW);
|
|
|
|
|
+
|
|
|
|
|
+ const U8Vec4* data = reinterpret_cast<const U8Vec4*>(&iloader.getSurface(0, 0, 0).m_data[0]);
|
|
|
|
|
|
|
|
const F32 epsilon = 1.0f / 255.0f;
|
|
const F32 epsilon = 1.0f / 255.0f;
|
|
|
- for(int y = 0; y < height; ++y)
|
|
|
|
|
|
|
+ for(U32 y = 0; y < iloader.getWidth(); ++y)
|
|
|
{
|
|
{
|
|
|
- for(int x = 0; x < width; ++x)
|
|
|
|
|
|
|
+ for(U32 x = 0; x < iloader.getHeight(); ++x)
|
|
|
{
|
|
{
|
|
|
- const U8Vec4& pixel = *(data + y * width + x);
|
|
|
|
|
|
|
+ const U8Vec4& pixel = *(data + y * iloader.getWidth() + x);
|
|
|
const F32 m = F32(pixel.z()) / 255.0f;
|
|
const F32 m = F32(pixel.z()) / 255.0f;
|
|
|
const F32 r = F32(pixel.y()) / 255.0f;
|
|
const F32 r = F32(pixel.y()) / 255.0f;
|
|
|
|
|
|
|
@@ -119,12 +89,10 @@ static Error identifyMetallicRoughnessTexture(CString fname, F32& constantMetali
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- stbi_image_free(data);
|
|
|
|
|
-
|
|
|
|
|
return Error::NONE;
|
|
return Error::NONE;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
|
|
|
|
+Error GltfImporter::writeMaterial(const cgltf_material& mtl)
|
|
|
{
|
|
{
|
|
|
StringAuto fname(m_alloc);
|
|
StringAuto fname(m_alloc);
|
|
|
fname.sprintf("%s%s.ankimtl", m_outDir.cstr(), mtl.name);
|
|
fname.sprintf("%s%s.ankimtl", m_outDir.cstr(), mtl.name);
|
|
@@ -139,7 +107,10 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
HashMapAuto<CString, StringAuto> extras(m_alloc);
|
|
HashMapAuto<CString, StringAuto> extras(m_alloc);
|
|
|
ANKI_CHECK(getExtras(mtl.extras, extras));
|
|
ANKI_CHECK(getExtras(mtl.extras, extras));
|
|
|
|
|
|
|
|
- std::string xml = XML_HEADER + std::string("\n") + MATERIAL_TEMPLATE;
|
|
|
|
|
|
|
+ StringAuto xml(m_alloc);
|
|
|
|
|
+ xml.append(XML_HEADER);
|
|
|
|
|
+ xml.append("\n");
|
|
|
|
|
+ xml.append(MATERIAL_TEMPLATE);
|
|
|
|
|
|
|
|
// Diffuse
|
|
// Diffuse
|
|
|
if(mtl.pbr_metallic_roughness.base_color_texture.texture)
|
|
if(mtl.pbr_metallic_roughness.base_color_texture.texture)
|
|
@@ -147,20 +118,19 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
StringAuto uri(m_alloc);
|
|
StringAuto uri(m_alloc);
|
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.base_color_texture).cstr());
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.base_color_texture).cstr());
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%diff%", "<input shaderInput=\"diffTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
|
|
|
|
|
- xml = replaceAllString(xml, "%diffTexMutator%", "1");
|
|
|
|
|
|
|
+ xml.replaceAll(
|
|
|
|
|
+ "%diff%", StringAuto{m_alloc}.sprintf("<input shaderInput=\"diffTex\" value=\"%s\"/>", uri.cstr()));
|
|
|
|
|
+ xml.replaceAll("%diffTexMutator%", "1");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
const F32* diffCol = &mtl.pbr_metallic_roughness.base_color_factor[0];
|
|
const F32* diffCol = &mtl.pbr_metallic_roughness.base_color_factor[0];
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml,
|
|
|
|
|
- "%diff%",
|
|
|
|
|
- "<input shaderInput=\"diffColor\" value=\"" + std::to_string(diffCol[0]) + " " + std::to_string(diffCol[1])
|
|
|
|
|
- + " " + std::to_string(diffCol[2]) + "\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll("%diff%",
|
|
|
|
|
+ StringAuto{m_alloc}.sprintf(
|
|
|
|
|
+ "<input shaderInput=\"diffColor\" value=\"%f %f %f\"/>", diffCol[0], diffCol[1], diffCol[2]));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%diffTexMutator%", "0");
|
|
|
|
|
|
|
+ xml.replaceAll("%diffTexMutator%", "0");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Specular color (freshnel)
|
|
// Specular color (freshnel)
|
|
@@ -189,11 +159,11 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
specular = Vec3(0.04f);
|
|
specular = Vec3(0.04f);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml,
|
|
|
|
|
- "%spec%",
|
|
|
|
|
- "<input shaderInput=\"specColor\" value=\"" + std::to_string(specular.x()) + " "
|
|
|
|
|
- + std::to_string(specular.y()) + " " + std::to_string(specular.z()) + "\"/>");
|
|
|
|
|
- xml = replaceAllString(xml, "%specTexMutator%", "0");
|
|
|
|
|
|
|
+ xml.replaceAll("%spec%",
|
|
|
|
|
+ StringAuto{m_alloc}.sprintf(
|
|
|
|
|
+ "<input shaderInput=\"specColor\" value=\"%f %f %f\"/>", specular.x(), specular.y(), specular.z()));
|
|
|
|
|
+
|
|
|
|
|
+ xml.replaceAll("%specTexMutator%", "0");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Identify metallic/roughness texture
|
|
// Identify metallic/roughness texture
|
|
@@ -202,7 +172,7 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
{
|
|
{
|
|
|
const CString fname = getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture);
|
|
const CString fname = getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture);
|
|
|
|
|
|
|
|
- ANKI_CHECK(identifyMetallicRoughnessTexture(fname, constantMetaliness, constantRoughness));
|
|
|
|
|
|
|
+ ANKI_CHECK(identifyMetallicRoughnessTexture(fname, constantMetaliness, constantRoughness, m_alloc));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Roughness
|
|
// Roughness
|
|
@@ -212,10 +182,10 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
uri.sprintf(
|
|
uri.sprintf(
|
|
|
"%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
|
|
"%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%roughness%", "<input shaderInput=\"roughnessTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll("%roughness%",
|
|
|
|
|
+ StringAuto{m_alloc}.sprintf("<input shaderInput=\"roughnessTex\" value=\"%s\"/>", uri.cstr()));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%roughnessTexMutator%", "1");
|
|
|
|
|
|
|
+ xml.replaceAll("%roughnessTexMutator%", "1");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -223,10 +193,10 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
? constantRoughness * mtl.pbr_metallic_roughness.roughness_factor
|
|
? constantRoughness * mtl.pbr_metallic_roughness.roughness_factor
|
|
|
: mtl.pbr_metallic_roughness.roughness_factor;
|
|
: mtl.pbr_metallic_roughness.roughness_factor;
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%roughness%", "<input shaderInput=\"roughness\" value=\"" + std::to_string(roughness) + "\" />");
|
|
|
|
|
|
|
+ xml.replaceAll(
|
|
|
|
|
+ "%roughness%", StringAuto{m_alloc}.sprintf("<input shaderInput=\"roughness\" value=\"%f\"/>", roughness));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%roughnessTexMutator%", "0");
|
|
|
|
|
|
|
+ xml.replaceAll("%roughnessTexMutator%", "0");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Metallic
|
|
// Metallic
|
|
@@ -236,10 +206,10 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
uri.sprintf(
|
|
uri.sprintf(
|
|
|
"%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
|
|
"%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%metallic%", "<input shaderInput=\"metallicTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll(
|
|
|
|
|
+ "%metallic%", StringAuto{m_alloc}.sprintf("<input shaderInput=\"metallicTex\" value=\"%s\"/>", uri.cstr()));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%metalTexMutator%", "1");
|
|
|
|
|
|
|
+ xml.replaceAll("%metalTexMutator%", "1");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -247,10 +217,10 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
? constantMetaliness * mtl.pbr_metallic_roughness.metallic_factor
|
|
? constantMetaliness * mtl.pbr_metallic_roughness.metallic_factor
|
|
|
: mtl.pbr_metallic_roughness.metallic_factor;
|
|
: mtl.pbr_metallic_roughness.metallic_factor;
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%metallic%", "<input shaderInput=\"metallic\" value=\"" + std::to_string(metalines) + "\" />");
|
|
|
|
|
|
|
+ xml.replaceAll(
|
|
|
|
|
+ "%metallic%", StringAuto{m_alloc}.sprintf("<input shaderInput=\"metallic\" value=\"%f\"/>", metalines));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%metalTexMutator%", "0");
|
|
|
|
|
|
|
+ xml.replaceAll("%metalTexMutator%", "0");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Normal texture
|
|
// Normal texture
|
|
@@ -259,15 +229,15 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
StringAuto uri(m_alloc);
|
|
StringAuto uri(m_alloc);
|
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.normal_texture).cstr());
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.normal_texture).cstr());
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%normal%", "<input shaderInput=\"normalTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll(
|
|
|
|
|
+ "%normal%", StringAuto{m_alloc}.sprintf("<input shaderInput=\"normalTex\" value=\"%s\"/>", uri.cstr()));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%normalTexMutator%", "1");
|
|
|
|
|
|
|
+ xml.replaceAll("%normalTexMutator%", "1");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- xml = replaceAllString(xml, "%normal%", "");
|
|
|
|
|
- xml = replaceAllString(xml, "%normalTexMutator%", "0");
|
|
|
|
|
|
|
+ xml.replaceAll("%normal%", "");
|
|
|
|
|
+ xml.replaceAll("%normalTexMutator%", "0");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Emissive texture
|
|
// Emissive texture
|
|
@@ -276,21 +246,22 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
StringAuto uri(m_alloc);
|
|
StringAuto uri(m_alloc);
|
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.emissive_texture).cstr());
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.emissive_texture).cstr());
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%emission%", "<input shaderInput=\"emissiveTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll(
|
|
|
|
|
+ "%emission%", StringAuto{m_alloc}.sprintf("<input shaderInput=\"emissiveTex\" value=\"%s\"/>", uri.cstr()));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%emissiveTexMutator%", "1");
|
|
|
|
|
|
|
+ xml.replaceAll("%emissiveTexMutator%", "1");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
const F32* emissionCol = &mtl.emissive_factor[0];
|
|
const F32* emissionCol = &mtl.emissive_factor[0];
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml,
|
|
|
|
|
- "%emission%",
|
|
|
|
|
- "<input shaderInput=\"emission\" value=\"" + std::to_string(emissionCol[0]) + " "
|
|
|
|
|
- + std::to_string(emissionCol[1]) + " " + std::to_string(emissionCol[2]) + "\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll("%emission%",
|
|
|
|
|
+ StringAuto{m_alloc}.sprintf("<input shaderInput=\"emission\" value=\"%f %f %f\"/>",
|
|
|
|
|
+ emissionCol[0],
|
|
|
|
|
+ emissionCol[1],
|
|
|
|
|
+ emissionCol[2]));
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%emissiveTexMutator%", "0");
|
|
|
|
|
|
|
+ xml.replaceAll("%emissiveTexMutator%", "0");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Subsurface
|
|
// Subsurface
|
|
@@ -306,8 +277,8 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
subsurface = 0.0f;
|
|
subsurface = 0.0f;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%subsurface%", "<input shaderInput=\"subsurface\" value=\"" + std::to_string(subsurface) + "\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll("%subsurface%",
|
|
|
|
|
+ StringAuto{m_alloc}.sprintf("<input shaderInput=\"subsurface\" value=\"%f\"/>", subsurface));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Height texture
|
|
// Height texture
|
|
@@ -317,34 +288,32 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
|
|
|
StringAuto uri(m_alloc);
|
|
StringAuto uri(m_alloc);
|
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), it->cstr());
|
|
uri.sprintf("%s%s", m_texrpath.cstr(), it->cstr());
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml,
|
|
|
|
|
- "%height%",
|
|
|
|
|
- "<input shaderInput=\"heightTex\" value=\"" + std::string(uri.cstr())
|
|
|
|
|
- + "\"/>\n"
|
|
|
|
|
- "\t\t<input shaderInput=\"heightMapScale\" value=\"0.05\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll("%height%",
|
|
|
|
|
+ StringAuto{m_alloc}.sprintf("<input shaderInput=\"heightTex\" value=\"%s\" \"/>\n"
|
|
|
|
|
+ "\t\t<input shaderInput=\"heightMapScale\" value=\"0.05\"/>",
|
|
|
|
|
+ uri.cstr()));
|
|
|
|
|
|
|
|
- xml = replaceAllString(
|
|
|
|
|
- xml, "%parallaxInput%", "<input shaderInput=\"modelViewMat\" builtin=\"MODEL_VIEW_MATRIX\"/>");
|
|
|
|
|
|
|
+ xml.replaceAll("%parallaxInput%", "<input shaderInput=\"modelViewMat\" builtin=\"MODEL_VIEW_MATRIX\"/>");
|
|
|
|
|
|
|
|
- xml = replaceAllString(xml, "%parallaxMutator%", "1");
|
|
|
|
|
|
|
+ xml.replaceAll("%parallaxMutator%", "1");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- xml = replaceAllString(xml, "%height%", "");
|
|
|
|
|
- xml = replaceAllString(xml, "%parallaxInput%", "");
|
|
|
|
|
- xml = replaceAllString(xml, "%parallaxMutator%", "0");
|
|
|
|
|
|
|
+ xml.replaceAll("%height%", "");
|
|
|
|
|
+ xml.replaceAll("%parallaxInput%", "");
|
|
|
|
|
+ xml.replaceAll("%parallaxMutator%", "0");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Replace texture extensions with .anki
|
|
// Replace texture extensions with .anki
|
|
|
- xml = replaceAllString(xml, ".tga", ".ankitex");
|
|
|
|
|
- xml = replaceAllString(xml, ".png", ".ankitex");
|
|
|
|
|
- xml = replaceAllString(xml, ".jpg", ".ankitex");
|
|
|
|
|
- xml = replaceAllString(xml, ".jpeg", ".ankitex");
|
|
|
|
|
|
|
+ xml.replaceAll(".tga", ".ankitex");
|
|
|
|
|
+ xml.replaceAll(".png", ".ankitex");
|
|
|
|
|
+ xml.replaceAll(".jpg", ".ankitex");
|
|
|
|
|
+ xml.replaceAll(".jpeg", ".ankitex");
|
|
|
|
|
|
|
|
// Write file
|
|
// Write file
|
|
|
File file;
|
|
File file;
|
|
|
ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::WRITE));
|
|
ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::WRITE));
|
|
|
- ANKI_CHECK(file.writeText("%s", xml.c_str()));
|
|
|
|
|
|
|
+ ANKI_CHECK(file.writeText("%s", xml.cstr()));
|
|
|
|
|
|
|
|
return Error::NONE;
|
|
return Error::NONE;
|
|
|
}
|
|
}
|