Skip to content

Commit

Permalink
VOXELFORMAT: VOX: refactored format to support references
Browse files Browse the repository at this point in the history
there are still problems with flip matrices and backside culling

see pull request #296 and issue #255

This more or less opens #275 again
  • Loading branch information
mgerhardy committed Jul 8, 2023
1 parent 53044ec commit 3b0acdf
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 67 deletions.
28 changes: 15 additions & 13 deletions src/modules/scenegraph/CoordinateSystemUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,31 @@

namespace scenegraph {

//
// Generate right, forward and up direction vectors to express the desired coordinate system as it would have been in opengl
//
// MV/VXL GL VENGI
//
// Z Y Y
// | Y | | Z
// |/ | |/
// o----X o----X o----X
// /
// Z
//
bool coordinateSystemToMatrix(CoordinateSystem sys, glm::mat4 &matrix) {
glm::vec3 right;
glm::vec3 up;
glm::vec3 forward;
switch (sys) {
case CoordinateSystem::Vengi:
right = glm::right;
up = glm::up;
forward = glm::forward;
right = glm::vec3(1.0f, 0.0f, 0.0f);
up = glm::vec3(0.0f, 1.0f, 0.0f);
forward = glm::vec3(0.0f, 0.0f, 1.0f);
break;
case CoordinateSystem::MagicaVoxel:
case CoordinateSystem::VXL:
//
// Z-up coordinate system (like 3dsmax).
//
// MV GL
//
// Z Y
// | Y |
// |/ |
// o----X o----X
// /
// Z
right = glm::vec3(1.0f, 0.0f, 0.0f);
up = glm::vec3(0.0f, 0.0f, 1.0f);
forward = glm::vec3(0.0f, 1.0f, 0.0f);
Expand Down
79 changes: 28 additions & 51 deletions src/modules/voxelformat/VoxFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,51 +42,28 @@ size_t VoxFormat::loadPalette(const core::String &filename, io::SeekableReadStre
bool VoxFormat::loadInstance(const ogt_vox_scene *scene, uint32_t ogt_instanceIdx, scenegraph::SceneGraph &sceneGraph,
int parent, core::DynamicArray<MVModelToNode> &models, const voxel::Palette &palette) {
const ogt_vox_instance &ogtInstance = scene->instances[ogt_instanceIdx];
const ogt_vox_model *ogtModel = scene->models[ogtInstance.model_index];
const glm::mat4 ogtMat = ogtTransformToMat(ogtInstance, 0, scene, ogtModel);
const glm::vec4 &ogtPivot = ogtVolumePivot(ogtModel);
const glm::ivec3 &ogtMins = calcTransform(ogtMat, glm::ivec3(0), ogtPivot);
const glm::ivec3 &ogtMaxs = calcTransform(ogtMat, ogtVolumeSize(ogtModel), ogtPivot);
const glm::ivec3 mins(-(ogtMins.x + 1), ogtMins.z, ogtMins.y);
const glm::ivec3 maxs(-(ogtMaxs.x + 1), ogtMaxs.z, ogtMaxs.y);
voxel::Region region(glm::min(mins, maxs), glm::max(mins, maxs));
const glm::ivec3 shift = region.getLowerCorner();
region.shift(-shift);
voxel::RawVolume *v = new voxel::RawVolume(region);
scenegraph::SceneGraphTransform transform;
transform.setWorldTranslation(shift);

const uint8_t *ogtVoxel = ogtModel->voxel_data;
for (uint32_t k = 0; k < ogtModel->size_z; ++k) {
for (uint32_t j = 0; j < ogtModel->size_y; ++j) {
for (uint32_t i = 0; i < ogtModel->size_x; ++i, ++ogtVoxel) {
if (ogtVoxel[0] == 0) {
continue;
}
const voxel::Voxel voxel = voxel::createVoxel(palette, ogtVoxel[0] - 1);
const glm::ivec3 &ogtPos = calcTransform(ogtMat, glm::ivec3(i, j, k), ogtPivot);
const glm::ivec3 pos(-(ogtPos.x + 1), ogtPos.z, ogtPos.y);
v->setVoxel(pos - shift, voxel);
}
}
scenegraph::SceneGraphNodeType type = scenegraph::SceneGraphNodeType::Model;
if (models[ogtInstance.model_index].nodeId != InvalidNodeId) {
type = scenegraph::SceneGraphNodeType::ModelReference;
}

scenegraph::SceneGraphNode node(scenegraph::SceneGraphNodeType::Model);
scenegraph::SceneGraphNode node(type);
loadKeyFrames(sceneGraph, node, ogtInstance, scene);
// TODO: we are overriding the keyframe data here
const scenegraph::KeyFrameIndex keyFrameIdx = 0;
node.setTransform(keyFrameIdx, transform);
node.setColor(instanceColor(scene, ogtInstance));
node.setName(instanceName(scene, ogtInstance));
node.setVisible(!instanceHidden(scene, ogtInstance));
node.setVolume(v, true);
// TODO: use already loaded models and create a model reference if needed
// TODO: node.setVolume(new voxel::RawVolume(models[ogtInstance.model_index].volume), true);
// TODO: set correct pivot
// TODO: node.setPivot({ogtPivot.x / (float)ogtModel->size_x, ogtPivot.z / (float)ogtModel->size_z, ogtPivot.y / (float)ogtModel->size_y});
// TODO: node.setPivot({(ogtPivot.x + 0.5f) / (float)ogtModel->size_x, (ogtPivot.z + 0.5f) / (float)ogtModel->size_z, (ogtPivot.y + 0.5f) / (float)ogtModel->size_y});
if (type == scenegraph::SceneGraphNodeType::ModelReference) {
node.setReference(models[ogtInstance.model_index].nodeId);
} else {
node.setVolume(models[ogtInstance.model_index].volume, true);
models[ogtInstance.model_index].volume = nullptr;
}
node.setPalette(palette);
return sceneGraph.emplace(core::move(node), parent) != -1;
const int nodeId = sceneGraph.emplace(core::move(node), parent);
if (nodeId != InvalidNodeId) {
models[ogtInstance.model_index].nodeId = nodeId;
return true;
}
return false;
}

bool VoxFormat::loadGroup(const ogt_vox_scene *scene, uint32_t ogt_groupIdx, scenegraph::SceneGraph &sceneGraph,
Expand Down Expand Up @@ -114,6 +91,18 @@ bool VoxFormat::loadGroup(const ogt_vox_scene *scene, uint32_t ogt_groupIdx, sce
return false;
}

for (uint32_t groupIdx = 0; groupIdx < scene->num_groups; ++groupIdx) {
const ogt_vox_group &group = scene->groups[groupIdx];
Log::debug("group %u with parent: %u (searching for %u)", groupIdx, group.parent_group_index, ogt_groupIdx);
if (group.parent_group_index != ogt_groupIdx) {
continue;
}
Log::debug("Found matching group (%u) with scene graph parent: %i", groupIdx, groupId);
if (!loadGroup(scene, groupIdx, sceneGraph, groupId, models, addedInstances, palette)) {
return false;
}
}

for (uint32_t n = 0; n < scene->num_instances; ++n) {
const ogt_vox_instance &ogtInstance = scene->instances[n];
if (ogtInstance.group_index != ogt_groupIdx) {
Expand All @@ -127,18 +116,6 @@ bool VoxFormat::loadGroup(const ogt_vox_scene *scene, uint32_t ogt_groupIdx, sce
}
}

for (uint32_t groupIdx = 0; groupIdx < scene->num_groups; ++groupIdx) {
const ogt_vox_group &group = scene->groups[groupIdx];
Log::debug("group %u with parent: %u (searching for %u)", groupIdx, group.parent_group_index, ogt_groupIdx);
if (group.parent_group_index != ogt_groupIdx) {
continue;
}
Log::debug("Found matching group (%u) with scene graph parent: %i", groupIdx, groupId);
if (!loadGroup(scene, groupIdx, sceneGraph, groupId, models, addedInstances, palette)) {
return false;
}
}

return true;
}

Expand Down
10 changes: 7 additions & 3 deletions src/modules/voxelformat/private/MagicaVoxel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "core/GLMConst.h"
#include "core/Log.h"
#include "core/StandardLib.h"
#include "scenegraph/CoordinateSystem.h"
#include "scenegraph/CoordinateSystemUtil.h"
#include "scenegraph/SceneGraph.h"
#include "scenegraph/SceneGraphNode.h"
#include "voxel/Palette.h"
Expand Down Expand Up @@ -60,8 +62,7 @@ bool loadKeyFrames(scenegraph::SceneGraph &sceneGraph, scenegraph::SceneGraphNod
sceneGraphKeyFrame.interpolation = scenegraph::InterpolationType::Linear;
sceneGraphKeyFrame.longRotation = false;
scenegraph::SceneGraphTransform &transform = sceneGraphKeyFrame.transform();
// TODO: scenegraph::convertCoordinateSystem(scenegraph::CoordinateSystem::MagicaVoxel, ogtMat));
transform.setWorldMatrix(ogtMat);
transform.setWorldMatrix(scenegraph::convertCoordinateSystem(scenegraph::CoordinateSystem::MagicaVoxel, ogtMat));
kf.push_back(sceneGraphKeyFrame);
}
return node.setKeyFrames(kf);
Expand Down Expand Up @@ -235,10 +236,13 @@ core::DynamicArray<MVModelToNode> loadModels(const ogt_vox_scene *scene, const v
continue;
}
const voxel::Voxel voxel = voxel::createVoxel(palette, ogtVoxel[0] - 1);
v->setVoxel(region.getUpperX() - (int)x, (int)z, (int)y, voxel);
v->setVoxel((int)x, (int)z, (int)y, voxel);
}
}
}
const glm::ivec3 shift(-(int)(ogtModel->size_x / 2), -(int)(ogtModel->size_z / 2), -(int)(ogtModel->size_y / 2));
v->translate(shift);

models.emplace_back(v, InvalidNodeId);
}
return models;
Expand Down

0 comments on commit 3b0acdf

Please sign in to comment.