voxel, animation, and pathfinding combined demo

This commit is contained in:
John McCardle 2026-02-05 22:57:08 -05:00
commit de5616f3a4
6 changed files with 730 additions and 2 deletions

View file

@ -259,6 +259,30 @@ int PyVoxelGrid::set_greedy_meshing(PyVoxelGridObject* self, PyObject* value, vo
return 0;
}
// Visible property
PyObject* PyVoxelGrid::get_visible(PyVoxelGridObject* self, void* closure) {
if (!self->data) {
PyErr_SetString(PyExc_RuntimeError, "VoxelGrid not initialized");
return nullptr;
}
return PyBool_FromLong(self->data->isVisible());
}
int PyVoxelGrid::set_visible(PyVoxelGridObject* self, PyObject* value, void* closure) {
if (!self->data) {
PyErr_SetString(PyExc_RuntimeError, "VoxelGrid not initialized");
return -1;
}
if (!PyBool_Check(value)) {
PyErr_SetString(PyExc_TypeError, "visible must be a boolean");
return -1;
}
self->data->setVisible(value == Py_True);
return 0;
}
// =============================================================================
// Voxel access methods
// =============================================================================
@ -1267,5 +1291,7 @@ PyGetSetDef PyVoxelGrid::getsetters[] = {
"Y-axis rotation in degrees.", nullptr},
{"greedy_meshing", (getter)get_greedy_meshing, (setter)set_greedy_meshing,
"Enable greedy meshing optimization (reduces vertex count for uniform regions).", nullptr},
{"visible", (getter)get_visible, (setter)set_visible,
"Show or hide this voxel grid in rendering.", nullptr},
{nullptr} // Sentinel
};

View file

@ -52,6 +52,10 @@ public:
static PyObject* get_greedy_meshing(PyVoxelGridObject* self, void* closure);
static int set_greedy_meshing(PyVoxelGridObject* self, PyObject* value, void* closure);
// Properties - visibility
static PyObject* get_visible(PyVoxelGridObject* self, void* closure);
static int set_visible(PyVoxelGridObject* self, PyObject* value, void* closure);
// Voxel access methods
static PyObject* get(PyVoxelGridObject* self, PyObject* args);
static PyObject* set(PyVoxelGridObject* self, PyObject* args);

View file

@ -1021,6 +1021,9 @@ void Viewport3D::renderVoxelLayers(const mat4& view, const mat4& proj) {
for (auto& pair : sortedLayers) {
VoxelGrid* grid = pair.first;
// Skip invisible grids
if (!grid->isVisible()) continue;
// Get vertices (triggers rebuild if dirty)
const std::vector<MeshVertex>& vertices = grid->getVertices();
if (vertices.empty()) continue;

View file

@ -64,6 +64,7 @@ private:
mutable bool meshDirty_ = true;
mutable std::vector<MeshVertex> cachedVertices_;
bool greedyMeshing_ = false; // Use greedy meshing algorithm
bool visible_ = true; // Visibility toggle for rendering
// Index calculation (row-major: X varies fastest, then Y, then Z)
inline size_t index(int x, int y, int z) const {
@ -163,6 +164,10 @@ public:
void setGreedyMeshing(bool enabled) { greedyMeshing_ = enabled; markDirty(); }
bool isGreedyMeshingEnabled() const { return greedyMeshing_; }
/// Show/hide this voxel grid in rendering
void setVisible(bool v) { visible_ = v; }
bool isVisible() const { return visible_; }
// Memory info (for debugging)
size_t memoryUsageBytes() const {
return data_.size() + materials_.size() * sizeof(VoxelMaterial);

View file

@ -235,8 +235,10 @@ void VoxelMesher::generateGreedyMesh(const VoxelGrid& grid, std::vector<MeshVert
} else { // Z-facing
float faceZ = (dir > 0) ? (sliceIdx + 1) * cs : sliceIdx * cs;
corner = vec3(u * cs, v * cs, faceZ);
uAxis = vec3(rectW * cs, 0, 0);
vAxis = vec3(0, rectH * cs, 0);
// Note: axes swapped vs X/Y cases to maintain CCW winding
// (vAxis × uAxis must equal +Z for front faces)
uAxis = vec3(0, rectH * cs, 0);
vAxis = vec3(rectW * cs, 0, 0);
normal = vec3(0, 0, static_cast<float>(dir));
if (dir < 0) std::swap(uAxis, vAxis);
}