VOXELFORMAT: hopefully fixed uv coordinates for palettes that don't have 256 colors

master
Martin Gerhardy 2022-05-22 18:37:20 +02:00
parent 2396a881ff
commit ad0e30841a
5 changed files with 47 additions and 34 deletions

View File

@ -152,7 +152,7 @@ Objects: {
if (withTexCoords) {
// 1 x 256 is the texture format that we are using for our palette
const float texcoord = 1.0f / (float)palette.colorCount;
const float texcoord = 1.0f / (float)voxel::PaletteMaxColors;
// it is only 1 pixel high - sample the middle
const float v1 = 0.5f;
wrapBool(stream.writeString("\t\tLayerElementUV: 0 {\n", false))

View File

@ -160,7 +160,7 @@ bool GLTFFormat::saveMeshes(const core::Map<int, int> &meshIdxNodeMap, const Sce
continue;
}
// 1 x 256 is the texture format that we are using for our palette
const float texcoord = 1.0f / (float)palette.colorCount;
const float texcoord = 1.0f / (float)voxel::PaletteMaxColors;
int meshExtIdx = 0;
meshIdxNodeMap.get(nodeId, meshExtIdx);

View File

@ -33,24 +33,18 @@ namespace voxelformat {
return false; \
}
bool OBJFormat::writeMtlFile(const core::String &mtlName, const core::String &paletteName) const {
const io::FilePtr &file = io::filesystem()->open(mtlName, io::FileMode::SysWrite);
if (!file->validHandle()) {
Log::error("Failed to create mtl file at %s", file->name().c_str());
bool OBJFormat::writeMtlFile(io::SeekableWriteStream &stream, const core::String &mtlId, const core::String &mapKd) const {
if (!stream.writeStringFormat(false, "\nnewmtl %s\n", mtlId.c_str())) {
Log::error("Failed to write obj newmtl");
return false;
}
io::FileStream stream(file);
wrapBool(stream.writeStringFormat(false, "# version " PROJECT_VERSION " github.com/mgerhardy/vengi\n"))
wrapBool(stream.writeStringFormat(false, "\n"))
wrapBool(stream.writeStringFormat(false, "newmtl palette\n"))
wrapBool(stream.writeStringFormat(false, "Ka 1.000000 1.000000 1.000000\n"))
wrapBool(stream.writeStringFormat(false, "Kd 1.000000 1.000000 1.000000\n"))
wrapBool(stream.writeStringFormat(false, "Ks 0.000000 0.000000 0.000000\n"))
wrapBool(stream.writeStringFormat(false, "Tr 1.000000\n"))
wrapBool(stream.writeStringFormat(false, "illum 1\n"))
wrapBool(stream.writeStringFormat(false, "Ns 0.000000\n"))
const core::String& paletteFilename = core::string::extractFilenameWithExtension(paletteName);
if (!stream.writeStringFormat(false, "map_Kd %s\n", paletteFilename.c_str())) {
wrapBool(stream.writeString("Ka 1.000000 1.000000 1.000000\n", false))
wrapBool(stream.writeString("Kd 1.000000 1.000000 1.000000\n", false))
wrapBool(stream.writeString("Ks 0.000000 0.000000 0.000000\n", false))
wrapBool(stream.writeString("Tr 1.000000\n", false))
wrapBool(stream.writeString("illum 1\n", false))
wrapBool(stream.writeString("Ns 0.000000\n", false))
if (!stream.writeStringFormat(false, "map_Kd %s\n", mapKd.c_str())) {
Log::error("Failed to write obj map_Kd");
return false;
}
@ -66,6 +60,21 @@ bool OBJFormat::saveMeshes(const core::Map<int, int> &, const SceneGraph &sceneG
Log::debug("Exporting %i layers", (int)meshes.size());
core::String mtlname = core::string::stripExtension(filename);
mtlname.append(".mtl");
Log::debug("Use mtl file: %s", mtlname.c_str());
const io::FilePtr &file = io::filesystem()->open(mtlname, io::FileMode::SysWrite);
if (!file->validHandle()) {
Log::error("Failed to create mtl file at %s", file->name().c_str());
return false;
}
io::FileStream matlstream(file);
wrapBool(matlstream.writeString("# version " PROJECT_VERSION " github.com/mgerhardy/vengi\n", false))
wrapBool(matlstream.writeString("\n", false))
core::Map<uint64_t, int> paletteMaterialIndices((int)sceneGraph.size());
int idxOffset = 0;
int texcoordOffset = 0;
for (const auto &meshExt : meshes) {
@ -80,17 +89,10 @@ bool OBJFormat::saveMeshes(const core::Map<int, int> &, const SceneGraph &sceneG
const SceneGraphNode &graphNode = sceneGraph.node(meshExt.nodeId);
const voxel::Palette &palette = graphNode.palette();
core::String mtlname = core::string::stripExtension(filename);
mtlname.append(core::String::format("%" PRIu64, palette.hash()));
mtlname.append(".mtl");
const core::String hashId = core::String::format("%" PRIu64, palette.hash());
core::String palettename = core::string::stripExtension(filename);
palettename.append(hashId);
palettename.append(".png");
// 1 x 256 is the texture format that we are using for our palette
const float texcoord = 1.0f / (float)palette.colorCount;
const float texcoord = 1.0f / (float)voxel::PaletteMaxColors;
// it is only 1 pixel high - sample the middle
const float v1 = 0.5f;
const glm::vec3 offset(mesh->getOffset());
@ -102,7 +104,10 @@ bool OBJFormat::saveMeshes(const core::Map<int, int> &, const SceneGraph &sceneG
}
stream.writeStringFormat(false, "o %s\n", objectName);
stream.writeStringFormat(false, "mtllib %s\n", core::string::extractFilenameWithExtension(mtlname).c_str());
wrapBool(stream.writeStringFormat(false, "usemtl palette\n"))
if (!stream.writeStringFormat(false, "usemtl %s\n", hashId.c_str())) {
Log::error("Failed to write obj usemtl %s\n", hashId.c_str());
return false;
}
for (int i = 0; i < nv; ++i) {
const voxel::VoxelVertex &v = vertices[i];
@ -175,11 +180,18 @@ bool OBJFormat::saveMeshes(const core::Map<int, int> &, const SceneGraph &sceneG
}
idxOffset += nv;
if (!writeMtlFile(mtlname, palettename)) {
return false;
}
if (!palette.save(palettename.c_str())) {
return false;
if (paletteMaterialIndices.find(palette.hash()) == paletteMaterialIndices.end()) {
core::String palettename = core::string::stripExtension(filename);
palettename.append(hashId);
palettename.append(".png");
paletteMaterialIndices.put(palette.hash(), 1);
const core::String &mapKd = core::string::extractFilenameWithExtension(palettename);
if (!writeMtlFile(matlstream, hashId, mapKd)) {
return false;
}
if (!palette.save(palettename.c_str())) {
return false;
}
}
}
return true;

View File

@ -5,6 +5,7 @@
#pragma once
#include "MeshFormat.h"
#include "io/Stream.h"
namespace tinyobj {
struct mesh_t;
@ -18,7 +19,7 @@ namespace voxelformat {
*/
class OBJFormat : public MeshFormat {
private:
bool writeMtlFile(const core::String& mtlName, const core::String &paletteName) const;
bool writeMtlFile(io::SeekableWriteStream &stream, const core::String &mtlId, const core::String &mapKd) const;
static void calculateAABB(const tinyobj::mesh_t &mesh, const tinyobj::attrib_t &attrib, glm::vec3 &mins,
glm::vec3 &maxs);
static void subdivideShape(const tinyobj::mesh_t &mesh, const core::StringMap<image::ImagePtr> &textures,

View File

@ -65,7 +65,7 @@ bool PLYFormat::saveMeshes(const core::Map<int, int> &, const SceneGraph &sceneG
const SceneGraphNode &graphNode = sceneGraph.node(meshExt.nodeId);
const voxel::Palette &palette = graphNode.palette();
// 1 x 256 is the texture format that we are using for our palette
const float texcoord = 1.0f / (float)palette.colorCount;
const float texcoord = 1.0f / (float)voxel::PaletteMaxColors;
// it is only 1 pixel high - sample the middle
const float v1 = 0.5f;