diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 0174656..1fc572f 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -94,16 +94,20 @@ void VoxelMesher::add_buffer(Ref voxels) { } void VoxelMesher::add_mesh_data_resource(Ref mesh, const Vector3 position, const Vector3 rotation, const Vector3 scale) { + Transform transform = Transform(Basis(rotation).scaled(scale), position); + + add_mesh_data_resource_transform(mesh, transform); +} + +void VoxelMesher::add_mesh_data_resource_transform(Ref mesh, const Transform transform) { ERR_FAIL_COND(mesh->get_array().size() == 0); - Transform local_transform = Transform(Basis(rotation).scaled(scale), position); - Array verts = mesh->get_array().get(Mesh::ARRAY_VERTEX); for (int i = 0; i < verts.size(); ++i) { Vector3 vert = verts[i]; - vert = local_transform.xform(vert); + vert = transform.xform(vert); add_vertex(vert); } @@ -116,7 +120,7 @@ void VoxelMesher::add_mesh_data_resource(Ref mesh, const Vecto for (int i = 0; i < normals.size(); ++i) { Vector3 normal = normals[i]; - normal = local_transform.basis.xform(normal); + normal = transform.basis.xform(normal); add_normal(normal); } @@ -461,6 +465,7 @@ void VoxelMesher::_bind_methods() { ClassDB::bind_method(D_METHOD("add_buffer", "buffer"), &VoxelMesher::add_buffer); ClassDB::bind_method(D_METHOD("add_mesh_data_resource", "mesh", "position", "rotation", "scale"), &VoxelMesher::add_mesh_data_resource, DEFVAL(Vector3(1.0, 1.0, 1.0)), DEFVAL(Vector3()), DEFVAL(Vector3())); + ClassDB::bind_method(D_METHOD("add_mesh_data_resource_transform", "transform"), &VoxelMesher::add_mesh_data_resource_transform); ClassDB::bind_method(D_METHOD("bake_colors", "buffer"), &VoxelMesher::bake_colors); ClassDB::bind_method(D_METHOD("get_voxel_scale"), &VoxelMesher::get_voxel_scale); diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h index ba28b5b..ff6c70a 100644 --- a/meshers/voxel_mesher.h +++ b/meshers/voxel_mesher.h @@ -37,6 +37,7 @@ public: void add_buffer(Ref voxels); void add_mesh_data_resource(Ref mesh, const Vector3 position = Vector3(0, 0, 0), const Vector3 rotation = Vector3(0, 0, 0), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); + void add_mesh_data_resource_transform(Ref mesh, const Transform transform); void bake_colors(Ref voxels); float get_voxel_scale() const; diff --git a/world/voxel_chunk.cpp b/world/voxel_chunk.cpp index cc5779b..d7c0814 100644 --- a/world/voxel_chunk.cpp +++ b/world/voxel_chunk.cpp @@ -369,6 +369,18 @@ void VoxelChunk::allocate_prop_mesh() { VS::get_singleton()->instance_set_transform(_prop_mesh_instance_rid, Transform(Basis(), Vector3(_chunk_position.x * _chunk_size.x * _voxel_scale, _chunk_position.y * _chunk_size.y * _voxel_scale, _chunk_position.z * _chunk_size.z * _voxel_scale))); } +void VoxelChunk::process_prop_lights() { + Transform transform(Basis().scaled(Vector3(_voxel_scale, _voxel_scale, _voxel_scale)), Vector3(_chunk_position.x * _chunk_size.x, _chunk_position.y * _chunk_size.y, _chunk_position.z * _chunk_size.z)); + + for (int i = 0; i < _props.size(); ++i) { + VCPropData prop = _props[i]; + + if (prop.prop.is_valid()) { + process_prop_light(prop.prop, transform); + } + } +} + void VoxelChunk::process_props() { if (_prop_mesh_rid == RID()) { allocate_prop_mesh(); @@ -377,16 +389,18 @@ void VoxelChunk::process_props() { for (int i = 0; i < _props.size(); ++i) { VCPropData prop = _props[i]; + Transform transform(Basis(prop.rotation).scaled(prop.scale), prop.position); + if (prop.mesh.is_valid()) { - _mesher->add_mesh_data_resource(prop.mesh, prop.position, prop.rotation, prop.scale); + _mesher->add_mesh_data_resource_transform(prop.mesh, transform); } if (prop.prop.is_valid()) { - process_prop(prop.prop); + process_prop(prop.prop, transform); } if (prop.scene.is_valid()) { - spawn_prop(prop.scene, prop.position, prop.rotation, prop.scale); + spawn_prop(prop.scene, transform); } } @@ -395,7 +409,7 @@ void VoxelChunk::process_props() { _mesher->build_mesh(_prop_mesh_rid); } -void VoxelChunk::process_prop(Ref prop, const Vector3 position, const Vector3 rotation, const Vector3 scale) { +void VoxelChunk::process_prop_light(Ref prop, const Transform transform) { ERR_FAIL_COND(!prop.is_valid()); for (int i = 0; i < prop->get_prop_count(); ++i) { @@ -404,32 +418,48 @@ void VoxelChunk::process_prop(Ref prop, const Vector3 position, co if (!data.is_valid()) continue; - Vector3 pos = position + data->get_position(); - Vector3 rot = (rotation + data->get_rotation()).normalized(); - Vector3 scl = scale * data->get_scale(); + Transform pt(Basis(data->get_rotation()).scaled(data->get_scale()), data->get_position()); - if (data->get_mesh().is_valid()) { - _mesher->add_mesh_data_resource(data->get_mesh(), pos, rot, scl); - } + pt = transform * pt; if (data->get_has_light()) { - Transform t = Transform(Basis(rot).scaled(scl), pos); - Vector3 lp = t.xform_inv(Vector3()); + Vector3 lp = pt.xform_inv(Vector3()); create_voxel_light(data->get_light_color(), data->get_light_size(), (int)lp.x, (int)lp.y, (int)lp.z); } - if (data->get_scene().is_valid()) { - spawn_prop(data->get_scene(), pos, rot, scl); - } - if (data->get_prop().is_valid()) { - process_prop(data->get_prop(), pos, rot, scl); + process_prop_light(data->get_prop(), pt); } } } -void VoxelChunk::spawn_prop(const Ref scene, const Vector3 position, const Vector3 rotation, const Vector3 scale) { +void VoxelChunk::process_prop(Ref prop, const Transform transform) { + ERR_FAIL_COND(!prop.is_valid()); + + for (int i = 0; i < prop->get_prop_count(); ++i) { + Ref data = prop->get_prop(i); + + if (!data.is_valid()) + continue; + + Transform pt(Basis(data->get_rotation()).scaled(data->get_scale()), data->get_position()); + + if (data->get_mesh().is_valid()) { + _mesher->add_mesh_data_resource_transform(data->get_mesh(), pt); + } + + if (data->get_scene().is_valid()) { + spawn_prop(data->get_scene(), pt); + } + + if (data->get_prop().is_valid()) { + process_prop(data->get_prop(), pt); + } + } +} + +void VoxelChunk::spawn_prop(const Ref scene, const Transform transform) { ERR_FAIL_COND(!scene.is_valid()); ERR_FAIL_COND(get_voxel_world() == NULL); @@ -446,8 +476,6 @@ void VoxelChunk::spawn_prop(const Ref scene, const Vector3 position ERR_FAIL_COND(spatial == NULL); - Transform transform = Transform(Basis(rotation).scaled(scale), position); - spatial->set_transform(transform); } @@ -790,9 +818,11 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("add_prop", "prop", "position", "rotation", "scale"), &VoxelChunk::add_prop, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); ClassDB::bind_method(D_METHOD("clear_props"), &VoxelChunk::clear_props); + ClassDB::bind_method(D_METHOD("process_prop_lights"), &VoxelChunk::process_prop_lights); ClassDB::bind_method(D_METHOD("process_props"), &VoxelChunk::process_props); - ClassDB::bind_method(D_METHOD("process_prop", "prop", "position", "rotation", "scale"), &VoxelChunk::add_prop_spawned, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); - ClassDB::bind_method(D_METHOD("spawn_prop", "scene", "position", "rotation", "scale"), &VoxelChunk::add_prop_spawned, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); + ClassDB::bind_method(D_METHOD("process_prop", "prop", "transform"), &VoxelChunk::process_prop, DEFVAL(Transform())); + ClassDB::bind_method(D_METHOD("process_prop_light", "prop", "transform"), &VoxelChunk::process_prop_light, DEFVAL(Transform())); + ClassDB::bind_method(D_METHOD("spawn_prop", "transform"), &VoxelChunk::spawn_prop, DEFVAL(Transform())); ClassDB::bind_method(D_METHOD("build_prop_meshes"), &VoxelChunk::build_prop_meshes); ClassDB::bind_method(D_METHOD("build_prop_collider"), &VoxelChunk::build_prop_collider); diff --git a/world/voxel_chunk.h b/world/voxel_chunk.h index f16122d..09b0da5 100644 --- a/world/voxel_chunk.h +++ b/world/voxel_chunk.h @@ -106,10 +106,12 @@ public: void add_prop_spawned(const Ref scene, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); void add_prop(const Ref prop, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); void clear_props(); - + + void process_prop_lights(); void process_props(); - void process_prop(Ref prop, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); - void spawn_prop(const Ref scene, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); + void process_prop(Ref prop, const Transform transform = Transform()); + void process_prop_light(Ref prop, const Transform transform = Transform()); + void spawn_prop(const Ref scene, const Transform transform = Transform()); void build_prop_meshes(); void build_prop_collider();