Now PropData can add lights into chunks.

This commit is contained in:
Relintai 2019-11-08 11:52:36 +01:00
parent 8ba8209bc2
commit 8bbc6da5d2
5 changed files with 122 additions and 19 deletions

0
master Normal file
View File

View File

@ -1,6 +1,7 @@
#include "prop_data.h"
#include "prop_data_prop.h"
#include "../world/voxel_chunk.h"
bool PropData::get_snap_to_mesh() {
return _snap_to_mesh;
@ -56,23 +57,103 @@ void PropData::set_props(const Vector<Variant> &props) {
}
void PropData::add_textures_into(Ref<TexturePacker> texture_packer) {
ERR_FAIL_COND(!texture_packer.is_valid());
for (int i = 0; i < _props.size(); ++i) {
Ref<PropDataEntry> entry = _props.get(i);
Ref<PropDataMesh> pmesh = entry;
if (pmesh.is_valid() && pmesh->get_texture().is_valid()) {
texture_packer->add_texture(pmesh->get_texture());
}
Ref<PropDataProp> pdataprop = entry;
if (pdataprop.is_valid() && pdataprop->get_prop().is_valid()) {
pdataprop->get_prop()->add_textures_into(texture_packer);
}
}
ERR_FAIL_COND(!texture_packer.is_valid());
for (int i = 0; i < _props.size(); ++i) {
Ref<PropDataEntry> entry = _props.get(i);
Ref<PropDataMesh> pmesh = entry;
if (pmesh.is_valid() && pmesh->get_texture().is_valid()) {
texture_packer->add_texture(pmesh->get_texture());
}
Ref<PropDataProp> pdataprop = entry;
if (pdataprop.is_valid() && pdataprop->get_prop().is_valid()) {
pdataprop->get_prop()->add_textures_into(texture_packer);
}
}
}
void PropData::add_prop_lights_into(VoxelChunk *chunk, Transform parent_transform, bool allow_snap) {
ERR_FAIL_COND(!ObjectDB::instance_validate(chunk));
for (int i = 0; i < _props.size(); ++i) {
Ref<PropDataEntry> entry = _props.get(i);
Ref<PropDataLight> pl = entry;
if (pl.is_valid()) {
Transform t = parent_transform * pl->get_transform();
Vector3 px = t.origin / chunk->get_voxel_scale();
Vector3i cp = chunk->get_chunk_position();
Vector3i cs = chunk->get_chunk_size();
Ref<VoxelLight> vl;
vl.instance();
vl->set_world_position(px.x + cp.x * cs.x, px.y + cp.y * cs.y, px.z + cp.z * cs.z);
vl->set_color(pl->get_light_color());
vl->set_size(pl->get_light_size());
chunk->add_prop_light(vl);
}
Ref<PropDataProp> pdataprop = entry;
if (pdataprop.is_valid() && pdataprop->get_prop().is_valid()) {
Ref<PropData> pd = pdataprop->get_prop();
if (allow_snap) {
if (pd->get_snap_to_mesh())
print_error(pd->get_name());
pd->add_prop_lights_into(chunk, get_next_snapped_prop_transform(chunk, parent_transform * pdataprop->get_transform(), pd->get_snap_to_mesh(), pd->get_snap_axis()), allow_snap);
} else {
pd->add_prop_lights_into(chunk, parent_transform * pdataprop->get_transform(), allow_snap);
}
}
}
}
void PropData::add_prop_lights_into_bind(Node *chunk, Transform parent_transform, bool allow_snap) {
VoxelChunk *c = Object::cast_to<VoxelChunk>(chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(c));
add_prop_lights_into(c, parent_transform, allow_snap);
}
Transform PropData::get_next_snapped_prop_transform(Spatial *s, Transform parent_transform, bool snap_to_mesh, Vector3 snap_axis) {
if (snap_to_mesh) {
Vector3 pos = s->to_global(parent_transform.origin);
Vector3 world_snap_axis = s->to_global(parent_transform.xform(snap_axis));
Vector3 world_snap_dir = world_snap_axis - pos;
world_snap_dir *= 100;
PhysicsDirectSpaceState *space_state = s->get_world()->get_direct_space_state();
ERR_FAIL_COND_V(space_state == NULL, parent_transform);
PhysicsDirectSpaceState::RayResult res;
if (space_state->intersect_ray(pos - world_snap_dir, pos + world_snap_dir, res, Set<RID>(), 1)) {
parent_transform.origin = s->to_local(res.position);
}
}
return parent_transform;
}
Transform PropData::get_next_snapped_prop_transform_bind(Node *spatial, Transform parent_transform, bool snap_to_mesh, Vector3 snap_axis) {
Spatial *s = Object::cast_to<VoxelChunk>(spatial);
ERR_FAIL_COND_V(!ObjectDB::instance_validate(s), parent_transform);
return get_next_snapped_prop_transform(s, parent_transform, snap_to_mesh, snap_axis);
}
PropData::PropData() {
@ -102,6 +183,9 @@ void PropData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_props"), &PropData::get_props);
ClassDB::bind_method(D_METHOD("set_props", "props"), &PropData::set_props);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "props", PROPERTY_HINT_NONE, "17/17:PropDataEntry", PROPERTY_USAGE_DEFAULT, "PropDataEntry"), "set_props", "get_props");
ClassDB::bind_method(D_METHOD("add_textures_into", "texture_packer"), &PropData::add_textures_into);
ClassDB::bind_method(D_METHOD("add_textures_into", "texture_packer"), &PropData::add_textures_into);
ClassDB::bind_method(D_METHOD("add_prop_lights_into", "chunk", "parent_transform", "allow_snap"), &PropData::add_prop_lights_into_bind);
ClassDB::bind_method(D_METHOD("get_next_snapped_prop_transform", "spatial", "parent_transform", "snap_to_mesh", "snap_axis"), &PropData::get_next_snapped_prop_transform_bind);
}

View File

@ -3,12 +3,18 @@
#include "core/reference.h"
#include "core/vector.h"
#include "core/math/transform.h"
#include "servers/physics_server.h"
#include "prop_data_entry.h"
#include "prop_data_mesh.h"
#include "../../texture_packer/texture_packer.h"
class Spatial;
class VoxelChunk;
class PropData : public Resource {
GDCLASS(PropData, Resource);
@ -30,6 +36,11 @@ public:
void set_props(const Vector<Variant> &props);
void add_textures_into(Ref<TexturePacker> texture_packer);
void add_prop_lights_into(VoxelChunk *chunk, Transform parent_transform, bool allow_snap);
void add_prop_lights_into_bind(Node *chunk, Transform parent_transform, bool allow_snap);
Transform get_next_snapped_prop_transform(Spatial *s, Transform parent_transform, bool snap_to_mesh, Vector3 snap_axis);
Transform get_next_snapped_prop_transform_bind(Node *spatial, Transform parent_transform, bool snap_to_mesh, Vector3 snap_axis);
PropData();
~PropData();

View File

@ -434,6 +434,10 @@ void VoxelChunk::clear_baked_lights() {
_buffer->clear_lights();
}
void VoxelChunk::add_prop_light(Ref<VoxelLight> light) {
bake_light(light);
}
void VoxelChunk::add_prop(Ref<VoxelChunkPropData> prop) {
_props.push_back(prop);
@ -853,6 +857,8 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("bake_lights"), &VoxelChunk::bake_lights);
ClassDB::bind_method(D_METHOD("bake_light", "light"), &VoxelChunk::bake_light);
ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunk::clear_baked_lights);
ClassDB::bind_method(D_METHOD("add_prop_light", "light"), &VoxelChunk::add_prop_light);
ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelChunk::add_prop);
ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelChunk::get_prop);

View File

@ -129,6 +129,8 @@ public:
void bake_lights();
void bake_light(Ref<VoxelLight> light);
void clear_baked_lights();
void add_prop_light(Ref<VoxelLight> light);
//props
void add_prop(Ref<VoxelChunkPropData> prop);