OverviewFilesCommitsIssuesDocsReleasesPeers

proc-nodes / src / nodes / volume_grid_nodes.h

81 lines · c ref:
#ifndef PROC_NODES_VOLUME_GRID_NODES_H
#define PROC_NODES_VOLUME_GRID_NODES_H

#include "../graph/proc_node.h"

namespace godot {

// ── THE VOXEL-GRID FAMILY ───────────────────────────────────────────────────
//
// Blender's SDF-grid nodes, which mountain_voronoi1.blend's MTN_Solidify is
// built from: mesh -> SDF grid -> fillet -> mesh. Without them that group is
// SKIPPED at import and the mountain arrives without its solidify pass --
// thinner and sharper than in Blender, with only a log line saying so.
//
// The grid itself is not new. ProcVolume has carried density_grid, grid_origin,
// grid_size and grid_resolution since it was written; these three nodes are what
// finally put something in it and take it out again. The evaluator and the
// extractor are libdc's -- DCGeneratorMeshSDF and dc_mesh_from_grid -- so no
// algorithm is written twice.
//
// ⚠ SIGN CONVENTION. libdc is POSITIVE = SOLID throughout, and these nodes keep
// that. Blender's SDF grids are negative inside. A grid that crosses the bridge
// is therefore sign-flipped relative to Blender's, which matters the moment
// anyone compares a raw grid value across the two; it does not matter for
// mesh -> grid -> mesh, which is what the mountain does.

// Mesh to SDF Grid — sample a mesh's signed distance into a ProcVolume grid.
class MeshToSDFGridNode : public ProcNode {
	GDCLASS(MeshToSDFGridNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "MeshToSDFGrid"; }
	String get_node_title() const override { return "Mesh to SDF Grid"; }
	String get_node_category() const override { return "Volume"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;

	MeshToSDFGridNode();
};

// SDF Grid Fillet — round the field's concave creases.
class SDFGridFilletNode : public ProcNode {
	GDCLASS(SDFGridFilletNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "SDFGridFillet"; }
	String get_node_title() const override { return "SDF Grid Fillet"; }
	String get_node_category() const override { return "Volume"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;

	SDFGridFilletNode();
};

// Grid to Mesh — extract the isosurface, through libdc's Dual Contouring.
class GridToMeshNode : public ProcNode {
	GDCLASS(GridToMeshNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "GridToMesh"; }
	String get_node_title() const override { return "Grid to Mesh"; }
	String get_node_category() const override { return "Volume"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;

	GridToMeshNode();
};

} // namespace godot

#endif // PROC_NODES_VOLUME_GRID_NODES_H