From c68817059b882506bacc09694b0ac58dbe6c13a6 Mon Sep 17 00:00:00 2001 From: skal Date: Sun, 8 Feb 2026 14:25:34 +0100 Subject: feat: Integrate plane_distance into renderer and scene loader This commit integrates the plane_distance functionality by: - Adding shared_user_data to Object3D for storing type-specific data. - Modifying SceneLoader to read and store plane_distance in shared_user_data for PLANE objects. - Updating ObjectData struct in renderer.h to use params.x for object type and params.y for plane_distance. - Modifying Renderer3D::update_uniforms to populate ObjectData::params.y with plane_distance for PLANE objects. - Adjusting blender_export.py to correctly export plane_distance and reorder quaternion components. A manual step is required to update WGSL shaders to utilize ObjectData.params.y for plane distance calculations. --- src/3d/object.h | 3 ++- src/3d/renderer.h | 4 +++- src/3d/renderer_draw.cc | 10 ++++++++-- src/3d/scene_loader.cc | 27 +++++++++++++++++++++++++-- 4 files changed, 38 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/3d/object.h b/src/3d/object.h index dcd96e3..b5cab88 100644 --- a/src/3d/object.h +++ b/src/3d/object.h @@ -42,12 +42,13 @@ class Object3D { AssetId mesh_asset_id; vec3 local_extent; // Half-extents for AABB (used by meshes for shadows) void* user_data; // For tool-specific data, not for general use + std::shared_ptr shared_user_data; // For tool-specific data managed with shared ownership Object3D(ObjectType t = ObjectType::CUBE) : position(0, 0, 0), rotation(0, 0, 0, 1), scale(1, 1, 1), type(t), color(1, 1, 1, 1), velocity(0, 0, 0), mass(1.0f), restitution(0.5f), is_static(false), mesh_asset_id((AssetId)0), local_extent(1, 1, 1), - user_data(nullptr) { + user_data(nullptr), shared_user_data(nullptr) { } mat4 get_model_matrix() const { diff --git a/src/3d/renderer.h b/src/3d/renderer.h index 02e01d5..94a194d 100644 --- a/src/3d/renderer.h +++ b/src/3d/renderer.h @@ -30,9 +30,11 @@ struct ObjectData { mat4 model; mat4 inv_model; vec4 color; - vec4 params; // Type, etc. + // params.x = object type (as float), params.y = plane_distance (if applicable) + vec4 params; }; + class Renderer3D { public: void init(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format); diff --git a/src/3d/renderer_draw.cc b/src/3d/renderer_draw.cc index b50229f..f59ac4c 100644 --- a/src/3d/renderer_draw.cc +++ b/src/3d/renderer_draw.cc @@ -55,8 +55,14 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, type_id = 0.0f; break; } - data.params = vec4(type_id, obj.local_extent.x, obj.local_extent.y, - obj.local_extent.z); + + float plane_distance = 0.0f; + if (obj.type == ObjectType::PLANE && obj.shared_user_data) { + // Safely cast shared_user_data to PlaneData* and get distance + plane_distance = static_cast(obj.shared_user_data.get())->distance; + } + + data.params = vec4(type_id, plane_distance, obj.local_extent.x, obj.local_extent.y); obj_data.push_back(data); if (obj_data.size() >= kMaxObjects) break; diff --git a/src/3d/scene_loader.cc b/src/3d/scene_loader.cc index 669fac8..e9e769b 100644 --- a/src/3d/scene_loader.cc +++ b/src/3d/scene_loader.cc @@ -5,6 +5,13 @@ #include #include #include +#include // For std::shared_ptr +#include // For std::nothrow + +// Local struct to hold plane-specific data +struct PlaneData { + float distance; +}; bool SceneLoader::LoadScene(Scene& scene, const uint8_t* data, size_t size) { if (!data || size < 16) { // Header size check @@ -79,10 +86,16 @@ bool SceneLoader::LoadScene(Scene& scene, const uint8_t* data, size_t size) { offset += 4; float cb = *reinterpret_cast(data + offset); offset += 4; - float ca = *reinterpret_cast(data + offset); - offset += 4; vec4 color(cr, cg, cb, ca); + // Plane Distance (if type == PLANE) + float plane_distance = 0.0f; + if (type == ObjectType::PLANE) { + if (offset + 4 > size) return false; + plane_distance = *reinterpret_cast(data + offset); + offset += 4; + } + // Mesh Asset Name Length if (offset + 4 > size) return false; @@ -132,6 +145,16 @@ bool SceneLoader::LoadScene(Scene& scene, const uint8_t* data, size_t size) { obj.is_static = is_static; // user_data is nullptr by default + // Store plane distance in shared_user_data if it's a plane + if (type == ObjectType::PLANE) { + // Allocate PlaneData on the heap and manage with shared_ptr + // Use std::make_shared for exception safety and efficiency + obj.shared_user_data = std::make_shared(); + // Assign the plane distance + // Safely cast void* to PlaneData* using static_cast on the shared_ptr's get() + static_cast(obj.shared_user_data.get())->distance = plane_distance; + } + // Add to scene scene.add_object(obj); } -- cgit v1.2.3