diff options
Diffstat (limited to 'scene/3d')
30 files changed, 947 insertions, 352 deletions
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 17ae553e5e..b72483d71b 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const { return monitoring; } -Array Area3D::get_overlapping_bodies() const { +TypedArray<Node3D> Area3D::get_overlapping_bodies() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; @@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const { return monitorable; } -Array Area3D::get_overlapping_areas() const { +TypedArray<Area3D> Area3D::get_overlapping_areas() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index ff6c0b6b08..f6503c6d2d 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -184,8 +184,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; - Array get_overlapping_areas() const; //function for script + TypedArray<Node3D> get_overlapping_bodies() const; + TypedArray<Area3D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 097368853e..5701d3cea2 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -385,8 +385,8 @@ void AudioStreamPlayer3D::_notification(int p_what) { linear_velocity = velocity_tracker->get_tracked_linear_velocity(); } - Ref<World3D> world = get_world(); - ERR_FAIL_COND(world.is_null()); + Ref<World3D> world_3d = get_world_3d(); + ERR_FAIL_COND(world_3d.is_null()); int new_output_count = 0; @@ -396,7 +396,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { //check if any area is diverting sound into a bus - PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world->get_space()); + PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space()); PhysicsDirectSpaceState3D::ShapeResult sr[MAX_INTERSECT_AREAS]; @@ -419,7 +419,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { } List<Camera3D *> cameras; - world->get_camera_list(&cameras); + world_3d->get_camera_list(&cameras); for (List<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) { @@ -556,7 +556,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { for (int i = 0; i < vol_index_max; i++) { - output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation); + output.reverb_vol[i] = output.reverb_vol[i].lerp(center_frame, attenuation); } } else { for (int i = 0; i < vol_index_max; i++) { @@ -567,7 +567,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { for (int i = 0; i < vol_index_max; i++) { - output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity); + output.reverb_vol[i] = output.vol[i].lerp(output.reverb_vol[i] * attenuation, uniformity); output.reverb_vol[i] *= area_send; } @@ -710,6 +710,11 @@ float AudioStreamPlayer3D::get_pitch_scale() const { void AudioStreamPlayer3D::play(float p_from_pos) { + if (!is_playing()) { + // Reset the prev_output_count if the stream is stopped + prev_output_count = 0; + } + if (stream_playback.is_valid()) { active = true; setplay = p_from_pos; diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 30ab4d463b..871f3119bc 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -95,8 +95,8 @@ void Camera3D::_update_camera() { get_viewport()->_camera_transform_changed_notify(); - if (get_world().is_valid()) { - get_world()->_update_camera(this); + if (get_world_3d().is_valid()) { + get_world_3d()->_update_camera(this); } } @@ -144,12 +144,12 @@ void Camera3D::_notification(int p_what) { } break; case NOTIFICATION_BECAME_CURRENT: { if (viewport) { - viewport->find_world()->_register_camera(this); + viewport->find_world_3d()->_register_camera(this); } } break; case NOTIFICATION_LOST_CURRENT: { if (viewport) { - viewport->find_world()->_remove_camera(this); + viewport->find_world_3d()->_remove_camera(this); } } break; } @@ -413,23 +413,6 @@ Vector3 Camera3D::project_position(const Point2 &p_point, float p_z_depth) const return get_camera_transform().xform(p); } -/* -void Camera::_camera_make_current(Node *p_camera) { - - - if (p_camera==this) { - RenderingServer::get_singleton()->viewport_attach_camera(viewport_id,camera); - active=true; - } else { - if (active && p_camera==NULL) { - //detech camera because no one else will claim it - RenderingServer::get_singleton()->viewport_attach_camera(viewport_id,RID()); - } - active=false; - } -} -*/ - void Camera3D::set_environment(const Ref<Environment> &p_environment) { environment = p_environment; @@ -706,7 +689,7 @@ Camera3D::Camera3D() { viewport = nullptr; force_change = false; mode = PROJECTION_PERSPECTIVE; - set_perspective(70.0, 0.05, 100.0); + set_perspective(75.0, 0.05, 100.0); keep_aspect = KEEP_HEIGHT; layers = 0xfffff; v_offset = 0; @@ -760,7 +743,7 @@ void ClippedCamera3D::_notification(int p_what) { return; } - PhysicsDirectSpaceState3D *dspace = get_world()->get_direct_space_state(); + PhysicsDirectSpaceState3D *dspace = get_world_3d()->get_direct_space_state(); ERR_FAIL_COND(!dspace); // most likely physics set to threads Vector3 cam_fw = -get_global_transform().basis.get_axis(Vector3::AXIS_Z).normalized(); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index e6cd7bfe7e..5d050e32b0 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -44,7 +44,7 @@ void CollisionObject3D::_notification(int p_what) { else PhysicsServer3D::get_singleton()->body_set_state(rid, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); - RID space = get_world()->get_space(); + RID space = get_world_3d()->get_space(); if (area) { PhysicsServer3D::get_singleton()->area_set_space(rid, space); } else diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 12c105b0f4..4c25f55f0b 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -69,6 +69,7 @@ void CPUParticles3D::set_amount(int p_amount) { for (int i = 0; i < p_amount; i++) { w[i].active = false; + w[i].custom[3] = 0.0; // Make sure w component isn't garbage data } } diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp new file mode 100644 index 0000000000..4c824aedc4 --- /dev/null +++ b/scene/3d/decal.cpp @@ -0,0 +1,235 @@ +/*************************************************************************/ +/* decal.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "decal.h" + +void Decal::set_extents(const Vector3 &p_extents) { + extents = p_extents; + RS::get_singleton()->decal_set_extents(decal, p_extents); + update_gizmo(); + _change_notify("extents"); +} + +Vector3 Decal::get_extents() const { + return extents; +} + +void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) { + ERR_FAIL_INDEX(p_type, TEXTURE_MAX); + textures[p_type] = p_texture; + RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RS::get_singleton()->decal_set_texture(decal, RS::DecalTexture(p_type), texture_rid); +} +Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const { + ERR_FAIL_INDEX_V(p_type, TEXTURE_MAX, Ref<Texture2D>()); + return textures[p_type]; +} + +void Decal::set_emission_energy(float p_energy) { + emission_energy = p_energy; + RS::get_singleton()->decal_set_emission_energy(decal, emission_energy); +} +float Decal::get_emission_energy() const { + return emission_energy; +} + +void Decal::set_albedo_mix(float p_mix) { + albedo_mix = p_mix; + RS::get_singleton()->decal_set_albedo_mix(decal, albedo_mix); +} +float Decal::get_albedo_mix() const { + return albedo_mix; +} + +void Decal::set_upper_fade(float p_fade) { + upper_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_upper_fade() const { + return upper_fade; +} + +void Decal::set_lower_fade(float p_fade) { + lower_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_lower_fade() const { + return lower_fade; +} + +void Decal::set_normal_fade(float p_fade) { + normal_fade = p_fade; + RS::get_singleton()->decal_set_normal_fade(decal, normal_fade); +} +float Decal::get_normal_fade() const { + return normal_fade; +} + +void Decal::set_modulate(Color p_modulate) { + modulate = p_modulate; + RS::get_singleton()->decal_set_modulate(decal, p_modulate); +} + +Color Decal::get_modulate() const { + return modulate; +} + +void Decal::set_enable_distance_fade(bool p_enable) { + distance_fade_enabled = p_enable; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +bool Decal::is_distance_fade_enabled() const { + return distance_fade_enabled; +} + +void Decal::set_distance_fade_begin(float p_distance) { + distance_fade_begin = p_distance; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_begin() const { + return distance_fade_begin; +} + +void Decal::set_distance_fade_length(float p_length) { + distance_fade_length = p_length; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_length() const { + return distance_fade_length; +} + +void Decal::set_cull_mask(uint32_t p_layers) { + cull_mask = p_layers; + RS::get_singleton()->decal_set_cull_mask(decal, cull_mask); +} +uint32_t Decal::get_cull_mask() const { + return cull_mask; +} + +AABB Decal::get_aabb() const { + + AABB aabb; + aabb.position = -extents; + aabb.size = extents * 2.0; + return aabb; +} +Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const { + + return Vector<Face3>(); +} + +void Decal::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents); + + ClassDB::bind_method(D_METHOD("set_texture", "type", "texture"), &Decal::set_texture); + ClassDB::bind_method(D_METHOD("get_texture", "type"), &Decal::get_texture); + + ClassDB::bind_method(D_METHOD("set_emission_energy", "energy"), &Decal::set_emission_energy); + ClassDB::bind_method(D_METHOD("get_emission_energy"), &Decal::get_emission_energy); + + ClassDB::bind_method(D_METHOD("set_albedo_mix", "energy"), &Decal::set_albedo_mix); + ClassDB::bind_method(D_METHOD("get_albedo_mix"), &Decal::get_albedo_mix); + + ClassDB::bind_method(D_METHOD("set_modulate", "color"), &Decal::set_modulate); + ClassDB::bind_method(D_METHOD("get_modulate"), &Decal::get_modulate); + + ClassDB::bind_method(D_METHOD("set_upper_fade", "fade"), &Decal::set_upper_fade); + ClassDB::bind_method(D_METHOD("get_upper_fade"), &Decal::get_upper_fade); + + ClassDB::bind_method(D_METHOD("set_lower_fade", "fade"), &Decal::set_lower_fade); + ClassDB::bind_method(D_METHOD("get_lower_fade"), &Decal::get_lower_fade); + + ClassDB::bind_method(D_METHOD("set_normal_fade", "fade"), &Decal::set_normal_fade); + ClassDB::bind_method(D_METHOD("get_normal_fade"), &Decal::get_normal_fade); + + ClassDB::bind_method(D_METHOD("set_enable_distance_fade", "enable"), &Decal::set_enable_distance_fade); + ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &Decal::is_distance_fade_enabled); + + ClassDB::bind_method(D_METHOD("set_distance_fade_begin", "distance"), &Decal::set_distance_fade_begin); + ClassDB::bind_method(D_METHOD("get_distance_fade_begin"), &Decal::get_distance_fade_begin); + + ClassDB::bind_method(D_METHOD("set_distance_fade_length", "distance"), &Decal::set_distance_fade_length); + ClassDB::bind_method(D_METHOD("get_distance_fade_length"), &Decal::get_distance_fade_length); + + ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &Decal::set_cull_mask); + ClassDB::bind_method(D_METHOD("get_cull_mask"), &Decal::get_cull_mask); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater"), "set_extents", "get_extents"); + ADD_GROUP("Textures", "texture_"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_GROUP("Parameters", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "albedo_mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_albedo_mix", "get_albedo_mix"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_normal_fade", "get_normal_fade"); + ADD_GROUP("Vertical Fade", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade"); + ADD_GROUP("Distance Fade", "distance_fade_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin"), "set_distance_fade_begin", "get_distance_fade_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_GROUP("Cull Mask", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); + + BIND_ENUM_CONSTANT(TEXTURE_ALBEDO); + BIND_ENUM_CONSTANT(TEXTURE_NORMAL); + BIND_ENUM_CONSTANT(TEXTURE_ORM); + BIND_ENUM_CONSTANT(TEXTURE_EMISSION); + BIND_ENUM_CONSTANT(TEXTURE_MAX); +} + +Decal::Decal() { + + extents = Vector3(1, 1, 1); + emission_energy = 1.0; + modulate = Color(1, 1, 1, 1); + albedo_mix = 1.0; + cull_mask = (1 << 20) - 1; + upper_fade = 0.3; + lower_fade = 0.3; + normal_fade = 0; + distance_fade_enabled = false; + distance_fade_begin = 10; + distance_fade_length = 1; + + decal = RenderingServer::get_singleton()->decal_create(); + RS::get_singleton()->instance_set_base(get_instance(), decal); +} + +Decal::~Decal() { + + RS::get_singleton()->free(decal); +} diff --git a/scene/3d/decal.h b/scene/3d/decal.h new file mode 100644 index 0000000000..665444829d --- /dev/null +++ b/scene/3d/decal.h @@ -0,0 +1,114 @@ +/*************************************************************************/ +/* decal.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef DECAL_H +#define DECAL_H + +#include "scene/3d/visual_instance_3d.h" +#include "scene/resources/texture.h" +#include "servers/rendering_server.h" + +class Decal : public VisualInstance3D { + GDCLASS(Decal, VisualInstance3D); + +public: + enum DecalTexture { + TEXTURE_ALBEDO, + TEXTURE_NORMAL, + TEXTURE_ORM, + TEXTURE_EMISSION, + TEXTURE_MAX + }; + +private: + RID decal; + Vector3 extents; + Ref<Texture2D> textures[TEXTURE_MAX]; + float emission_energy; + float albedo_mix; + Color modulate; + uint32_t cull_mask; + float normal_fade; + float upper_fade; + float lower_fade; + bool distance_fade_enabled; + float distance_fade_begin; + float distance_fade_length; + +protected: + static void _bind_methods(); + +public: + void set_extents(const Vector3 &p_extents); + Vector3 get_extents() const; + + void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture(DecalTexture p_type) const; + + void set_emission_energy(float p_energy); + float get_emission_energy() const; + + void set_albedo_mix(float p_mix); + float get_albedo_mix() const; + + void set_modulate(Color p_modulate); + Color get_modulate() const; + + void set_upper_fade(float p_energy); + float get_upper_fade() const; + + void set_lower_fade(float p_fade); + float get_lower_fade() const; + + void set_normal_fade(float p_fade); + float get_normal_fade() const; + + void set_enable_distance_fade(bool p_enable); + bool is_distance_fade_enabled() const; + + void set_distance_fade_begin(float p_distance); + float get_distance_fade_begin() const; + + void set_distance_fade_length(float p_length); + float get_distance_fade_length() const; + + void set_cull_mask(uint32_t p_layers); + uint32_t get_cull_mask() const; + + virtual AABB get_aabb() const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; + + Decal(); + ~Decal(); +}; + +VARIANT_ENUM_CAST(Decal::DecalTexture); + +#endif // DECAL_H diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index be3b369724..c048f60ebd 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -70,7 +70,7 @@ void Light3D::set_shadow(bool p_enable) { shadow = p_enable; RS::get_singleton()->light_set_shadow(light, p_enable); - if (type == RenderingServer::LIGHT_SPOT) { + if (type == RenderingServer::LIGHT_SPOT || type == RenderingServer::LIGHT_OMNI) { update_configuration_warning(); } } @@ -166,6 +166,18 @@ Light3D::BakeMode Light3D::get_bake_mode() const { return bake_mode; } +void Light3D::set_projector(const Ref<Texture2D> &p_texture) { + + projector = p_texture; + RID tex_id = projector.is_valid() ? projector->get_rid() : RID(); + RS::get_singleton()->light_set_projector(light, tex_id); + update_configuration_warning(); +} + +Ref<Texture2D> Light3D::get_projector() const { + return projector; +} + void Light3D::_update_visibility() { if (!is_inside_tree()) @@ -217,8 +229,16 @@ bool Light3D::is_editor_only() const { void Light3D::_validate_property(PropertyInfo &property) const { - if (RenderingServer::get_singleton()->is_low_end() && property.name == "shadow_contact") { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") { + property.usage = 0; + } + + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") { + property.usage = 0; + } + + if (get_light_type() != RS::LIGHT_DIRECTIONAL && property.name == "light_angular_distance") { + property.usage = 0; } } @@ -251,10 +271,16 @@ void Light3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode); ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode); + ClassDB::bind_method(D_METHOD("set_projector", "projector"), &Light3D::set_projector); + ClassDB::bind_method(D_METHOD("get_projector"), &Light3D::get_projector); + ADD_GROUP("Light", "light_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disable,Indirect,All"), "set_bake_mode", "get_bake_mode"); @@ -262,9 +288,11 @@ void Light3D::_bind_methods() { ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0.1,8,0.01"), "set_param", "get_param", PARAM_SHADOW_BLUR); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); ADD_GROUP("", ""); @@ -273,10 +301,10 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(PARAM_SPECULAR); BIND_ENUM_CONSTANT(PARAM_RANGE); + BIND_ENUM_CONSTANT(PARAM_SIZE); BIND_ENUM_CONSTANT(PARAM_ATTENUATION); BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION); - BIND_ENUM_CONSTANT(PARAM_CONTACT_SHADOW_SIZE); BIND_ENUM_CONSTANT(PARAM_SHADOW_MAX_DISTANCE); BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_1_OFFSET); BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_2_OFFSET); @@ -284,7 +312,9 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_SHADOW_FADE_START); BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS); - BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE); + BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR); + BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(PARAM_MAX); BIND_ENUM_CONSTANT(BAKE_DISABLED); @@ -318,17 +348,20 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_INDIRECT_ENERGY, 1); set_param(PARAM_SPECULAR, 0.5); set_param(PARAM_RANGE, 5); + set_param(PARAM_SIZE, 0); set_param(PARAM_ATTENUATION, 1); set_param(PARAM_SPOT_ANGLE, 45); set_param(PARAM_SPOT_ATTENUATION, 1); - set_param(PARAM_CONTACT_SHADOW_SIZE, 0); set_param(PARAM_SHADOW_MAX_DISTANCE, 0); set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1); set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2); set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5); set_param(PARAM_SHADOW_FADE_START, 0.8); - set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0); - set_param(PARAM_SHADOW_BIAS, 0.15); + set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0); + set_param(PARAM_SHADOW_BLUR, 1.0); + set_param(PARAM_SHADOW_BIAS, 0.02); + set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); + set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); set_param(PARAM_SHADOW_FADE_START, 1); set_disable_scale(true); } @@ -398,10 +431,9 @@ void DirectionalLight3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_fade_start", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_FADE_START); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE); ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_EXP_RANGE, "0,1024,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE); BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); @@ -414,11 +446,8 @@ void DirectionalLight3D::_bind_methods() { DirectionalLight3D::DirectionalLight3D() : Light3D(RenderingServer::LIGHT_DIRECTIONAL) { - set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8); - set_param(PARAM_SHADOW_BIAS, 0.1); set_param(PARAM_SHADOW_MAX_DISTANCE, 100); set_param(PARAM_SHADOW_FADE_START, 0.8); - set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE); @@ -436,6 +465,19 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const { return shadow_mode; } +String OmniLight3D::get_configuration_warning() const { + String warning = Light3D::get_configuration_warning(); + + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + + return warning; +} + void OmniLight3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight3D::set_shadow_mode); @@ -467,6 +509,13 @@ String SpotLight3D::get_configuration_warning() const { warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows."); } + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + return warning; } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 197e5854ec..6e78217342 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -46,10 +46,10 @@ public: PARAM_INDIRECT_ENERGY = RS::LIGHT_PARAM_INDIRECT_ENERGY, PARAM_SPECULAR = RS::LIGHT_PARAM_SPECULAR, PARAM_RANGE = RS::LIGHT_PARAM_RANGE, + PARAM_SIZE = RS::LIGHT_PARAM_SIZE, PARAM_ATTENUATION = RS::LIGHT_PARAM_ATTENUATION, PARAM_SPOT_ANGLE = RS::LIGHT_PARAM_SPOT_ANGLE, PARAM_SPOT_ATTENUATION = RS::LIGHT_PARAM_SPOT_ATTENUATION, - PARAM_CONTACT_SHADOW_SIZE = RS::LIGHT_PARAM_CONTACT_SHADOW_SIZE, PARAM_SHADOW_MAX_DISTANCE = RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE, PARAM_SHADOW_SPLIT_1_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET, PARAM_SHADOW_SPLIT_2_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET, @@ -57,7 +57,9 @@ public: PARAM_SHADOW_FADE_START = RS::LIGHT_PARAM_SHADOW_FADE_START, PARAM_SHADOW_NORMAL_BIAS = RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS, - PARAM_SHADOW_BIAS_SPLIT_SCALE = RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE, + PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR, + PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS, PARAM_MAX = RS::LIGHT_PARAM_MAX }; @@ -79,6 +81,7 @@ private: bool editor_only; void _update_visibility(); BakeMode bake_mode; + Ref<Texture2D> projector; // bind helpers @@ -123,6 +126,9 @@ public: void set_bake_mode(BakeMode p_mode); BakeMode get_bake_mode() const; + void set_projector(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_projector() const; + virtual AABB get_aabb() const; virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; @@ -194,6 +200,8 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; + virtual String get_configuration_warning() const; + OmniLight3D(); }; diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index d56a095a5b..cdc8db8aea 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -307,19 +307,22 @@ Ref<Material> MeshInstance3D::get_surface_material(int p_surface) const { Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { - if (get_material_override() != Ref<Material>()) { - return get_material_override(); - } else if (p_surface < materials.size()) { - return materials[p_surface]; - } else { - Ref<Mesh> mesh = get_mesh(); + Ref<Material> material_override = get_material_override(); + if (material_override.is_valid()) { + return material_override; + } - if (mesh.is_null() || p_surface >= mesh->get_surface_count()) { - return Ref<Material>(); - } + Ref<Material> surface_material = get_surface_material(p_surface); + if (surface_material.is_valid()) { + return surface_material; + } + Ref<Mesh> mesh = get_mesh(); + if (mesh.is_valid()) { return mesh->surface_get_material(p_surface); } + + return Ref<Material>(); } void MeshInstance3D::_mesh_changed() { diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 0b7407e049..913a3ea49f 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -507,12 +507,12 @@ bool Node3D::is_set_as_toplevel() const { return data.toplevel; } -Ref<World3D> Node3D::get_world() const { +Ref<World3D> Node3D::get_world_3d() const { ERR_FAIL_COND_V(!is_inside_world(), Ref<World3D>()); ERR_FAIL_COND_V(!data.viewport, Ref<World3D>()); - return data.viewport->find_world(); + return data.viewport->find_world_3d(); } void Node3D::_propagate_visibility_changed() { @@ -756,7 +756,7 @@ void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_set_as_toplevel"), &Node3D::is_set_as_toplevel); ClassDB::bind_method(D_METHOD("set_disable_scale", "disable"), &Node3D::set_disable_scale); ClassDB::bind_method(D_METHOD("is_scale_disabled"), &Node3D::is_scale_disabled); - ClassDB::bind_method(D_METHOD("get_world"), &Node3D::get_world); + ClassDB::bind_method(D_METHOD("get_world_3d"), &Node3D::get_world_3d); ClassDB::bind_method(D_METHOD("force_update_transform"), &Node3D::force_update_transform); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index f97a8a97dc..a4191eb2b3 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -124,7 +124,7 @@ public: Node3D *get_parent_spatial() const; - Ref<World3D> get_world() const; + Ref<World3D> get_world_3d() const; void set_translation(const Vector3 &p_translation); void set_rotation(const Vector3 &p_euler_rad); diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index f06135f53d..4a425d1e0e 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -316,16 +316,14 @@ void PathFollow3D::set_offset(float p_offset) { offset = p_offset; if (path) { - if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { + if (path->get_curve().is_valid()) { float path_length = path->get_curve()->get_baked_length(); if (loop) { - while (offset > path_length) - offset -= path_length; - - while (offset < 0) - offset += path_length; - + offset = Math::fposmod(offset, path_length); + if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { + offset = path_length; + } } else { offset = CLAMP(offset, 0, path_length); } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 2b6eb8ac8a..3991efc7c0 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } -Array PhysicsBody3D::get_collision_exceptions() { +TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -2134,6 +2134,10 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_joint_offset", "offset"), &PhysicalBone3D::set_joint_offset); ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset); + ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation); + ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation); + ClassDB::bind_method(D_METHOD("set_joint_rotation_degrees", "euler_degrees"), &PhysicalBone3D::set_joint_rotation_degrees); + ClassDB::bind_method(D_METHOD("get_joint_rotation_degrees"), &PhysicalBone3D::get_joint_rotation_degrees); ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset); ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset); @@ -2159,9 +2163,23 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone3D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone3D::get_gravity_scale); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &PhysicalBone3D::set_linear_damp); + ClassDB::bind_method(D_METHOD("get_linear_damp"), &PhysicalBone3D::get_linear_damp); + + ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &PhysicalBone3D::set_angular_damp); + ClassDB::bind_method(D_METHOD("get_angular_damp"), &PhysicalBone3D::get_angular_damp); + + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); + ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); + ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); @@ -2170,6 +2188,17 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); @@ -2187,6 +2216,19 @@ Skeleton3D *PhysicalBone3D::find_skeleton_parent(Node *p_parent) { return s ? s : find_skeleton_parent(p_parent->get_parent()); } +void PhysicalBone3D::_update_joint_offset() { + _fix_joint_offset(); + + set_ignore_transform_notification(true); + reset_to_rest_position(); + set_ignore_transform_notification(false); + +#ifdef TOOLS_ENABLED + if (get_gizmo().is_valid()) + get_gizmo()->redraw(); +#endif +} + void PhysicalBone3D::_fix_joint_offset() { // Clamp joint origin to bone origin if (parent_skeleton) { @@ -2370,16 +2412,31 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const { void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { joint_offset = p_offset; - _fix_joint_offset(); + _update_joint_offset(); + _change_notify("joint_rotation_degrees"); +} - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); +const Transform &PhysicalBone3D::get_joint_offset() const { + return joint_offset; +} -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif +void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) { + joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale()); + + _update_joint_offset(); + _change_notify("joint_offset"); +} + +Vector3 PhysicalBone3D::get_joint_rotation() const { + return joint_offset.basis.get_rotation(); +} + +void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) { + set_joint_rotation(p_euler_deg * Math_PI / 180.0); +} + +Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { + return get_joint_rotation() * 180.0 / Math_PI; } const Transform &PhysicalBone3D::get_body_offset() const { @@ -2390,20 +2447,7 @@ void PhysicalBone3D::set_body_offset(const Transform &p_offset) { body_offset = p_offset; body_offset_inverse = body_offset.affine_inverse(); - _fix_joint_offset(); - - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); - -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif -} - -const Transform &PhysicalBone3D::get_joint_offset() const { - return joint_offset; + _update_joint_offset(); } void PhysicalBone3D::set_simulate_physics(bool p_simulate) { @@ -2496,6 +2540,43 @@ real_t PhysicalBone3D::get_gravity_scale() const { return gravity_scale; } +void PhysicalBone3D::set_linear_damp(real_t p_linear_damp) { + ERR_FAIL_COND(p_linear_damp < -1); + linear_damp = p_linear_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp); +} + +real_t PhysicalBone3D::get_linear_damp() const { + return linear_damp; +} + +void PhysicalBone3D::set_angular_damp(real_t p_angular_damp) { + ERR_FAIL_COND(p_angular_damp < -1); + angular_damp = p_angular_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp); +} + +real_t PhysicalBone3D::get_angular_damp() const { + return angular_damp; +} + +void PhysicalBone3D::set_can_sleep(bool p_active) { + can_sleep = p_active; + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active); +} + +bool PhysicalBone3D::is_able_to_sleep() const { + return can_sleep; +} + +void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +} + PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC), #ifdef TOOLS_ENABLED @@ -2510,7 +2591,10 @@ PhysicalBone3D::PhysicalBone3D() : bounce(0), mass(1), friction(1), - gravity_scale(1) { + gravity_scale(1), + linear_damp(-1), + angular_damp(-1), + can_sleep(true) { reset_physics_simulation_state(); } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index bf7854b68d..0e719f5108 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -68,7 +68,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody3D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -562,6 +562,9 @@ private: real_t mass; real_t friction; real_t gravity_scale; + real_t linear_damp; + real_t angular_damp; + bool can_sleep; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -575,6 +578,7 @@ protected: private: static Skeleton3D *find_skeleton_parent(Node *p_parent); + void _update_joint_offset(); void _fix_joint_offset(); void _reload_joint(); @@ -599,6 +603,12 @@ public: void set_joint_offset(const Transform &p_offset); const Transform &get_joint_offset() const; + void set_joint_rotation(const Vector3 &p_euler_rad); + Vector3 get_joint_rotation() const; + + void set_joint_rotation_degrees(const Vector3 &p_euler_deg); + Vector3 get_joint_rotation_degrees() const; + void set_body_offset(const Transform &p_offset); const Transform &get_body_offset() const; @@ -624,6 +634,18 @@ public: void set_gravity_scale(real_t p_gravity_scale); real_t get_gravity_scale() const; + void set_linear_damp(real_t p_linear_damp); + real_t get_linear_damp() const; + + void set_angular_damp(real_t p_angular_damp); + real_t get_angular_damp() const; + + void set_can_sleep(bool p_active); + bool is_able_to_sleep() const; + + void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse); diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 591c17a91e..140d887d9a 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -807,6 +807,9 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_LINEAR_DAMPING); BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_TARGET_VELOCITY); BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_FORCE_LIMIT); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_STIFFNESS); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_DAMPING); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_LOWER_LIMIT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_UPPER_LIMIT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_SOFTNESS); @@ -816,6 +819,9 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANGULAR_ERP); BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_STIFFNESS); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_DAMPING); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); BIND_ENUM_CONSTANT(PARAM_MAX); BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_LIMIT); diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index a18da61656..304a5e1254 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -196,7 +196,7 @@ void RayCast3D::_notification(int p_what) { } void RayCast3D::_update_raycast_state() { - Ref<World3D> w3d = get_world(); + Ref<World3D> w3d = get_world_3d(); ERR_FAIL_COND(w3d.is_null()); PhysicsDirectSpaceState3D *dss = PhysicsServer3D::get_singleton()->space_get_direct_state(w3d->get_space()); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 59a6e23005..973822653a 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "core/message_queue.h" #include "core/project_settings.h" +#include "core/type_info.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/surface_tool.h" @@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect } } -void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { +void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) { set_physics_process_internal(false); Vector<int> sim_bones; @@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { sim_bones.resize(p_bones.size()); int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { - Variant::Type type = p_bones.get(i).get_type(); - if (Variant::STRING == type || Variant::STRING_NAME == type) { - int bone_id = find_bone(p_bones.get(i)); - if (bone_id != -1) - sim_bones.write[c++] = bone_id; - } + int bone_id = find_bone(p_bones[i]); + if (bone_id != -1) + sim_bones.write[c++] = bone_id; } sim_bones.resize(c); } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 08b8691658..0bccd3f8fc 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -222,7 +222,7 @@ private: public: void physical_bones_stop_simulation(); - void physical_bones_start_simulation_on(const Array &p_bones); + void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones); void physical_bones_add_collision_exception(RID p_exception); void physical_bones_remove_collision_exception(RID p_exception); #endif // _3D_DISABLED diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 7366290ed3..10bdd71d73 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -287,14 +287,22 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove return; // Skip solving } - p_task->skeleton->clear_bones_global_pose_override(); + p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, true); + + if (p_task->chain.middle_chain_item) { + p_task->skeleton->set_bone_global_pose_override(p_task->chain.middle_chain_item->bone, Transform(), 0.0, true); + } + + for (int i = 0; i < p_task->chain.tips.size(); i += 1) { + p_task->skeleton->set_bone_global_pose_override(p_task->chain.tips[i].chain_item->bone, Transform(), 0.0, true); + } make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta); update_chain(p_task->skeleton, &p_task->chain.chain_root); if (p_use_magnet && p_task->chain.middle_chain_item) { - p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.linear_interpolate(p_magnet_position, blending_delta); + p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta); solve_simple(p_task, true); } solve_simple(p_task, false); diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 6092818252..850ffab292 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -270,7 +270,7 @@ void SoftBody3D::_notification(int p_what) { add_change_receptor(this); } - RID space = get_world()->get_space(); + RID space = get_world_3d()->get_space(); PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, space); prepare_physics_server(); } break; diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 281be3f7d3..1410b730fd 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -45,15 +45,15 @@ void SpringArm3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(true); + set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(false); + set_physics_process_internal(false); } break; - case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: process_spring(); break; } @@ -147,7 +147,7 @@ void SpringArm3D::process_spring() { if (shape.is_null()) { motion = Vector3(cast_direction * (spring_length)); PhysicsDirectSpaceState3D::RayResult r; - bool intersected = get_world()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask); + bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask); if (intersected) { float dist = get_global_transform().origin.distance_to(r.position); dist -= margin; @@ -155,7 +155,7 @@ void SpringArm3D::process_spring() { } } else { motion = Vector3(cast_direction * spring_length); - get_world()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask); + get_world_3d()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask); } current_spring_length = spring_length * motion_delta; diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp index 2f657fe7b1..2707a0a514 100644 --- a/scene/3d/visibility_notifier_3d.cpp +++ b/scene/3d/visibility_notifier_3d.cpp @@ -68,7 +68,7 @@ void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) { aabb = p_aabb; if (is_inside_world()) { - get_world()->_update_notifier(this, get_global_transform().xform(aabb)); + get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb)); } _change_notify("aabb"); @@ -85,15 +85,15 @@ void VisibilityNotifier3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - get_world()->_register_notifier(this, get_global_transform().xform(aabb)); + get_world_3d()->_register_notifier(this, get_global_transform().xform(aabb)); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - get_world()->_update_notifier(this, get_global_transform().xform(aabb)); + get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb)); } break; case NOTIFICATION_EXIT_WORLD: { - get_world()->_remove_notifier(this); + get_world_3d()->_remove_notifier(this); } break; } } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 775a9b76e2..ce8672c1dd 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -60,8 +60,8 @@ void VisualInstance3D::_notification(int p_what) { if (skeleton) RenderingServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() ); */ - ERR_FAIL_COND(get_world().is_null()); - RenderingServer::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario()); + ERR_FAIL_COND(get_world_3d().is_null()); + RenderingServer::get_singleton()->instance_set_scenario(instance, get_world_3d()->get_scenario()); _update_visibility(); } break; @@ -217,6 +217,62 @@ float GeometryInstance3D::get_lod_max_hysteresis() const { void GeometryInstance3D::_notification(int p_what) { } +const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { + StringName *r = instance_uniform_property_remap.getptr(p_name); + if (!r) { + String s = p_name; + if (s.begins_with("shader_params/")) { + StringName name = s.replace("shader_params/", ""); + instance_uniform_property_remap[p_name] = name; + return instance_uniform_property_remap.getptr(p_name); + } + + return nullptr; + } + + return r; +} + +bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + set_shader_instance_uniform(*r, p_value); + return true; + } + + return false; +} + +bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + r_ret = get_shader_instance_uniform(*r); + return true; + } + + return false; +} +void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { + List<PropertyInfo> pinfo; + RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + PropertyInfo pi = E->get(); + bool has_def_value = false; + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); + if (def_value.get_type() != Variant::NIL) { + has_def_value = true; + } + if (instance_uniforms.has(pi.name)) { + pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : 0); + } else { + pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : 0); //do not save if not changed + } + + pi.name = "shader_params/" + pi.name; + p_list->push_back(pi); + } +} + void GeometryInstance3D::set_flag(Flags p_flag, bool p_value) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); @@ -258,6 +314,22 @@ float GeometryInstance3D::get_extra_cull_margin() const { return extra_cull_margin; } +void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) { + + if (p_value.get_type() == Variant::NIL) { + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, def_value); + instance_uniforms.erase(p_value); + } else { + instance_uniforms[p_uniform] = p_value; + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value); + } +} + +Variant GeometryInstance3D::get_shader_instance_uniform(const StringName &p_uniform) const { + + return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_uniform); +} void GeometryInstance3D::set_custom_aabb(AABB aabb) { RS::get_singleton()->instance_set_custom_aabb(get_instance(), aabb); @@ -280,6 +352,9 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lod_max_distance", "mode"), &GeometryInstance3D::set_lod_max_distance); ClassDB::bind_method(D_METHOD("get_lod_max_distance"), &GeometryInstance3D::get_lod_max_distance); + ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("set_lod_min_hysteresis", "mode"), &GeometryInstance3D::set_lod_min_hysteresis); ClassDB::bind_method(D_METHOD("get_lod_min_hysteresis"), &GeometryInstance3D::get_lod_min_hysteresis); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 9476c28848..cc5f92066f 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -108,9 +108,18 @@ private: float lod_min_hysteresis; float lod_max_hysteresis; + mutable HashMap<StringName, Variant> instance_uniforms; + mutable HashMap<StringName, StringName> instance_uniform_property_remap; + float extra_cull_margin; + const StringName *_instance_uniform_get_remap(const StringName p_name) const; + protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + void _notification(int p_what); static void _bind_methods(); @@ -139,6 +148,9 @@ public: void set_extra_cull_margin(float p_margin); float get_extra_cull_margin() const; + void set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value); + Variant get_shader_instance_uniform(const StringName &p_uniform) const; + void set_custom_aabb(AABB aabb); GeometryInstance3D(); diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 203c3cd812..f30c58be55 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -592,22 +592,16 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; const Vector3 *vr = vertices.ptr(); Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; - const Vector2 *uvr; + const Vector2 *uvr = nullptr; Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL]; - const Vector3 *nr; + const Vector3 *nr = nullptr; Vector<int> index = a[Mesh::ARRAY_INDEX]; - bool read_uv = false; - bool read_normals = false; - if (uv.size()) { - uvr = uv.ptr(); - read_uv = true; } if (normals.size()) { - read_normals = true; nr = normals.ptr(); } @@ -626,13 +620,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[ir[j * 3 + k]]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[ir[j * 3 + k]]; } @@ -659,13 +653,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[j * 3 + k]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[j * 3 + k]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[j * 3 + k]; } diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 8cf4554653..8dbb709ae4 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -36,50 +36,50 @@ void WorldEnvironment::_notification(int p_what) { if (p_what == Node3D::NOTIFICATION_ENTER_WORLD || p_what == Node3D::NOTIFICATION_ENTER_TREE) { if (environment.is_valid()) { - if (get_viewport()->find_world()->get_environment().is_valid()) { + if (get_viewport()->find_world_3d()->get_environment().is_valid()) { WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); } - get_viewport()->find_world()->set_environment(environment); - add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + get_viewport()->find_world_3d()->set_environment(environment); + add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } if (camera_effects.is_valid()) { - if (get_viewport()->find_world()->get_camera_effects().is_valid()) { + if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) { WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding."); } - get_viewport()->find_world()->set_camera_effects(camera_effects); - add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + get_viewport()->find_world_3d()->set_camera_effects(camera_effects); + add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } } else if (p_what == Node3D::NOTIFICATION_EXIT_WORLD || p_what == Node3D::NOTIFICATION_EXIT_TREE) { - if (environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) { - get_viewport()->find_world()->set_environment(Ref<Environment>()); - remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) { + get_viewport()->find_world_3d()->set_environment(Ref<Environment>()); + remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } - if (camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) { - get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>()); - remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) { + get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); + remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } } } void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) { - if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) { - get_viewport()->find_world()->set_environment(Ref<Environment>()); - remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) { + get_viewport()->find_world_3d()->set_environment(Ref<Environment>()); + remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); //clean up } environment = p_environment; if (is_inside_tree() && environment.is_valid()) { - if (get_viewport()->find_world()->get_environment().is_valid()) { + if (get_viewport()->find_world_3d()->get_environment().is_valid()) { WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); } - get_viewport()->find_world()->set_environment(environment); - add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + get_viewport()->find_world_3d()->set_environment(environment); + add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } update_configuration_warning(); @@ -92,19 +92,19 @@ Ref<Environment> WorldEnvironment::get_environment() const { void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) { - if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) { - get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>()); - remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) { + get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); + remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); //clean up } camera_effects = p_camera_effects; if (is_inside_tree() && camera_effects.is_valid()) { - if (get_viewport()->find_world()->get_camera_effects().is_valid()) { + if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) { WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding."); } - get_viewport()->find_world()->set_camera_effects(camera_effects); - add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + get_viewport()->find_world_3d()->set_camera_effects(camera_effects); + add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } update_configuration_warning(); @@ -125,7 +125,7 @@ String WorldEnvironment::get_configuration_warning() const { return String(); List<Node *> nodes; - get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()), &nodes); + get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), &nodes); if (nodes.size() > 1) { return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/xr_nodes.cpp index 537c094ceb..6f41629bac 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_nodes.cpp */ +/* xr_nodes.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,25 +28,25 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_nodes.h" -#include "core/input/input_filter.h" -#include "servers/arvr/arvr_interface.h" -#include "servers/arvr_server.h" +#include "xr_nodes.h" +#include "core/input/input.h" +#include "servers/xr/xr_interface.h" +#include "servers/xr_server.h" //////////////////////////////////////////////////////////////////////////////////////////////////// -void ARVRCamera::_notification(int p_what) { +void XRCamera3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - // need to find our ARVROrigin parent and let it know we're its camera! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // need to find our XROrigin3D parent and let it know we're its camera! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin != nullptr) { origin->set_tracked_camera(this); } }; break; case NOTIFICATION_EXIT_TREE: { - // need to find our ARVROrigin parent and let it know we're no longer its camera! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // need to find our XROrigin3D parent and let it know we're no longer its camera! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin != nullptr) { origin->clear_tracked_camera_if(this); } @@ -54,26 +54,26 @@ void ARVRCamera::_notification(int p_what) { }; }; -String ARVRCamera::get_configuration_warning() const { +String XRCamera3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); - // must be child node of ARVROrigin! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // must be child node of XROrigin3D! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - return TTR("ARVRCamera must have an ARVROrigin node as its parent."); + return TTR("XRCamera3D must have an XROrigin3D node as its parent."); }; return String(); }; -Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector3()); +Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector3()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::project_local_ray_normal(p_pos); } @@ -84,20 +84,20 @@ Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const { Vector2 cpos = get_viewport()->get_camera_coords(p_pos); Vector3 ray; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); Vector2 screen_he = cm.get_viewport_half_extents(); ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_znear()).normalized(); return ray; }; -Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector2()); +Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector2()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::unproject_position(p_pos); } @@ -106,7 +106,7 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const { Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); Plane p(get_camera_transform().xform_inv(p_pos), 1.0); @@ -120,13 +120,13 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const { return res; }; -Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector3()); +Vector3 XRCamera3D::project_position(const Point2 &p_point, float p_z_depth) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector3()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::project_position(p_point, p_z_depth); } @@ -135,7 +135,7 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); Vector2 vp_he = cm.get_viewport_half_extents(); @@ -149,13 +149,13 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con return get_camera_transform().xform(p); }; -Vector<Plane> ARVRCamera::get_frustum() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector<Plane>()); +Vector<Plane> XRCamera3D::get_frustum() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector<Plane>()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::get_frustum(); } @@ -163,21 +163,21 @@ Vector<Plane> ARVRCamera::get_frustum() const { ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>()); Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); return cm.get_projection_planes(get_camera_transform()); }; -ARVRCamera::ARVRCamera(){ +XRCamera3D::XRCamera3D(){ // nothing to do here yet for now.. }; -ARVRCamera::~ARVRCamera(){ +XRCamera3D::~XRCamera3D(){ // nothing to do here yet for now.. }; //////////////////////////////////////////////////////////////////////////////////////////////////// -void ARVRController::_notification(int p_what) { +void XRController3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { set_process_internal(true); @@ -186,12 +186,12 @@ void ARVRController::_notification(int p_what) { set_process_internal(false); }; break; case NOTIFICATION_INTERNAL_PROCESS: { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); // find the tracker for our controller - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { // this controller is currently turned off is_active = false; @@ -206,7 +206,7 @@ void ARVRController::_notification(int p_what) { // check button states for (int i = 0; i < 16; i++) { bool was_pressed = (button_states & mask) == mask; - bool is_pressed = InputFilter::get_singleton()->is_joy_button_pressed(joy_id, i); + bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i); if (!was_pressed && is_pressed) { emit_signal("button_pressed", i); @@ -236,49 +236,49 @@ void ARVRController::_notification(int p_what) { }; }; -void ARVRController::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id); - ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id); +void XRController3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &XRController3D::set_controller_id); + ClassDB::bind_method(D_METHOD("get_controller_id"), &XRController3D::get_controller_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_controller_id", "get_controller_id"); - ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name); + ClassDB::bind_method(D_METHOD("get_controller_name"), &XRController3D::get_controller_name); // passthroughs to information about our related joystick - ClassDB::bind_method(D_METHOD("get_joystick_id"), &ARVRController::get_joystick_id); - ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &ARVRController::is_button_pressed); - ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &ARVRController::get_joystick_axis); + ClassDB::bind_method(D_METHOD("get_joystick_id"), &XRController3D::get_joystick_id); + ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &XRController3D::is_button_pressed); + ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &XRController3D::get_joystick_axis); - ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active); - ClassDB::bind_method(D_METHOD("get_hand"), &ARVRController::get_hand); + ClassDB::bind_method(D_METHOD("get_is_active"), &XRController3D::get_is_active); + ClassDB::bind_method(D_METHOD("get_hand"), &XRController3D::get_hand); - ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRController::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRController::set_rumble); + ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble); + ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); ADD_PROPERTY_DEFAULT("rumble", 0.0); - ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRController::get_mesh); + ClassDB::bind_method(D_METHOD("get_mesh"), &XRController3D::get_mesh); ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button"))); ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button"))); ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"))); }; -void ARVRController::set_controller_id(int p_controller_id) { +void XRController3D::set_controller_id(int p_controller_id) { // We don't check any bounds here, this controller may not yet be active and just be a place holder until it is. // Note that setting this to 0 means this node is not bound to a controller yet. controller_id = p_controller_id; update_configuration_warning(); }; -int ARVRController::get_controller_id(void) const { +int XRController3D::get_controller_id(void) const { return controller_id; }; -String ARVRController::get_controller_name(void) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, String()); +String XRController3D::get_controller_name(void) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, String()); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { return String("Not connected"); }; @@ -286,12 +286,12 @@ String ARVRController::get_controller_name(void) const { return tracker->get_name(); }; -int ARVRController::get_joystick_id() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 0); +int XRController3D::get_joystick_id() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 0); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { // No tracker? no joystick id... (0 is our first joystick) return -1; @@ -300,30 +300,30 @@ int ARVRController::get_joystick_id() const { return tracker->get_joy_id(); }; -bool ARVRController::is_button_pressed(int p_button) const { +bool XRController3D::is_button_pressed(int p_button) const { int joy_id = get_joystick_id(); if (joy_id == -1) { return false; }; - return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button); + return Input::get_singleton()->is_joy_button_pressed(joy_id, p_button); }; -float ARVRController::get_joystick_axis(int p_axis) const { +float XRController3D::get_joystick_axis(int p_axis) const { int joy_id = get_joystick_id(); if (joy_id == -1) { return 0.0; }; - return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis); + return Input::get_singleton()->get_joy_axis(joy_id, p_axis); }; -real_t ARVRController::get_rumble() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 0.0); +real_t XRController3D::get_rumble() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 0.0); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { return 0.0; }; @@ -331,46 +331,46 @@ real_t ARVRController::get_rumble() const { return tracker->get_rumble(); }; -void ARVRController::set_rumble(real_t p_rumble) { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XRController3D::set_rumble(real_t p_rumble) { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker != nullptr) { tracker->set_rumble(p_rumble); }; }; -Ref<Mesh> ARVRController::get_mesh() const { +Ref<Mesh> XRController3D::get_mesh() const { return mesh; } -bool ARVRController::get_is_active() const { +bool XRController3D::get_is_active() const { return is_active; }; -ARVRPositionalTracker::TrackerHand ARVRController::get_hand() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, ARVRPositionalTracker::TRACKER_HAND_UNKNOWN); +XRPositionalTracker::TrackerHand XRController3D::get_hand() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { - return ARVRPositionalTracker::TRACKER_HAND_UNKNOWN; + return XRPositionalTracker::TRACKER_HAND_UNKNOWN; }; return tracker->get_hand(); }; -String ARVRController::get_configuration_warning() const { +String XRController3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); - // must be child node of ARVROrigin! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // must be child node of XROrigin! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - return TTR("ARVRController must have an ARVROrigin node as its parent."); + return TTR("XRController3D must have an XROrigin3D node as its parent."); }; if (controller_id == 0) { @@ -380,19 +380,19 @@ String ARVRController::get_configuration_warning() const { return String(); }; -ARVRController::ARVRController() { +XRController3D::XRController3D() { controller_id = 1; is_active = true; button_states = 0; }; -ARVRController::~ARVRController(){ +XRController3D::~XRController3D(){ // nothing to do here yet for now.. }; //////////////////////////////////////////////////////////////////////////////////////////////////// -void ARVRAnchor::_notification(int p_what) { +void XRAnchor3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { set_process_internal(true); @@ -401,12 +401,12 @@ void ARVRAnchor::_notification(int p_what) { set_process_internal(false); }; break; case NOTIFICATION_INTERNAL_PROCESS: { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); // find the tracker for our anchor - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); if (tracker == nullptr) { // this anchor is currently not available is_active = false; @@ -415,7 +415,7 @@ void ARVRAnchor::_notification(int p_what) { Transform transform; // we'll need our world_scale - real_t world_scale = arvr_server->get_world_scale(); + real_t world_scale = xr_server->get_world_scale(); // get our info from our tracker transform.basis = tracker->get_orientation(); @@ -427,7 +427,7 @@ void ARVRAnchor::_notification(int p_what) { transform.basis.orthonormalize(); // apply our reference frame and set our transform - set_transform(arvr_server->get_reference_frame() * transform); + set_transform(xr_server->get_reference_frame() * transform); // check for an updated mesh Ref<Mesh> trackerMesh = tracker->get_mesh(); @@ -442,43 +442,43 @@ void ARVRAnchor::_notification(int p_what) { }; }; -void ARVRAnchor::_bind_methods() { +void XRAnchor3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &ARVRAnchor::set_anchor_id); - ClassDB::bind_method(D_METHOD("get_anchor_id"), &ARVRAnchor::get_anchor_id); + ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &XRAnchor3D::set_anchor_id); + ClassDB::bind_method(D_METHOD("get_anchor_id"), &XRAnchor3D::get_anchor_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_anchor_id", "get_anchor_id"); - ClassDB::bind_method(D_METHOD("get_anchor_name"), &ARVRAnchor::get_anchor_name); + ClassDB::bind_method(D_METHOD("get_anchor_name"), &XRAnchor3D::get_anchor_name); - ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRAnchor::get_is_active); - ClassDB::bind_method(D_METHOD("get_size"), &ARVRAnchor::get_size); + ClassDB::bind_method(D_METHOD("get_is_active"), &XRAnchor3D::get_is_active); + ClassDB::bind_method(D_METHOD("get_size"), &XRAnchor3D::get_size); - ClassDB::bind_method(D_METHOD("get_plane"), &ARVRAnchor::get_plane); + ClassDB::bind_method(D_METHOD("get_plane"), &XRAnchor3D::get_plane); - ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRAnchor::get_mesh); + ClassDB::bind_method(D_METHOD("get_mesh"), &XRAnchor3D::get_mesh); ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"))); }; -void ARVRAnchor::set_anchor_id(int p_anchor_id) { +void XRAnchor3D::set_anchor_id(int p_anchor_id) { // We don't check any bounds here, this anchor may not yet be active and just be a place holder until it is. // Note that setting this to 0 means this node is not bound to an anchor yet. anchor_id = p_anchor_id; update_configuration_warning(); }; -int ARVRAnchor::get_anchor_id(void) const { +int XRAnchor3D::get_anchor_id(void) const { return anchor_id; }; -Vector3 ARVRAnchor::get_size() const { +Vector3 XRAnchor3D::get_size() const { return size; }; -String ARVRAnchor::get_anchor_name(void) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, String()); +String XRAnchor3D::get_anchor_name(void) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, String()); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); if (tracker == nullptr) { return String("Not connected"); }; @@ -486,18 +486,18 @@ String ARVRAnchor::get_anchor_name(void) const { return tracker->get_name(); }; -bool ARVRAnchor::get_is_active() const { +bool XRAnchor3D::get_is_active() const { return is_active; }; -String ARVRAnchor::get_configuration_warning() const { +String XRAnchor3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); - // must be child node of ARVROrigin! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // must be child node of XROrigin3D! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - return TTR("ARVRAnchor must have an ARVROrigin node as its parent."); + return TTR("XRAnchor3D must have an XROrigin3D node as its parent."); }; if (anchor_id == 0) { @@ -507,7 +507,7 @@ String ARVRAnchor::get_configuration_warning() const { return String(); }; -Plane ARVRAnchor::get_plane() const { +Plane XRAnchor3D::get_plane() const { Vector3 location = get_translation(); Basis orientation = get_transform().basis; @@ -516,67 +516,67 @@ Plane ARVRAnchor::get_plane() const { return plane; }; -Ref<Mesh> ARVRAnchor::get_mesh() const { +Ref<Mesh> XRAnchor3D::get_mesh() const { return mesh; } -ARVRAnchor::ARVRAnchor() { +XRAnchor3D::XRAnchor3D() { anchor_id = 1; is_active = true; }; -ARVRAnchor::~ARVRAnchor(){ +XRAnchor3D::~XRAnchor3D(){ // nothing to do here yet for now.. }; //////////////////////////////////////////////////////////////////////////////////////////////////// -String ARVROrigin::get_configuration_warning() const { +String XROrigin3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); if (tracked_camera == nullptr) - return TTR("ARVROrigin requires an ARVRCamera child node."); + return TTR("XROrigin3D requires an XRCamera3D child node."); return String(); }; -void ARVROrigin::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &ARVROrigin::set_world_scale); - ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVROrigin::get_world_scale); +void XROrigin3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &XROrigin3D::set_world_scale); + ClassDB::bind_method(D_METHOD("get_world_scale"), &XROrigin3D::get_world_scale); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale"); }; -void ARVROrigin::set_tracked_camera(ARVRCamera *p_tracked_camera) { +void XROrigin3D::set_tracked_camera(XRCamera3D *p_tracked_camera) { tracked_camera = p_tracked_camera; }; -void ARVROrigin::clear_tracked_camera_if(ARVRCamera *p_tracked_camera) { +void XROrigin3D::clear_tracked_camera_if(XRCamera3D *p_tracked_camera) { if (tracked_camera == p_tracked_camera) { tracked_camera = nullptr; }; }; -float ARVROrigin::get_world_scale() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 1.0); +float XROrigin3D::get_world_scale() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 1.0); - return arvr_server->get_world_scale(); + return xr_server->get_world_scale(); }; -void ARVROrigin::set_world_scale(float p_world_scale) { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XROrigin3D::set_world_scale(float p_world_scale) { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); - arvr_server->set_world_scale(p_world_scale); + xr_server->set_world_scale(p_world_scale); }; -void ARVROrigin::_notification(int p_what) { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XROrigin3D::_notification(int p_what) { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -587,13 +587,13 @@ void ARVROrigin::_notification(int p_what) { }; break; case NOTIFICATION_INTERNAL_PROCESS: { // set our world origin to our node transform - arvr_server->set_world_origin(get_global_transform()); + xr_server->set_world_origin(get_global_transform()); // check if we have a primary interface - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_valid() && tracked_camera != nullptr) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_valid() && tracked_camera != nullptr) { // get our positioning transform for our headset - Transform t = arvr_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform()); + Transform t = xr_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform()); // now apply this to our camera tracked_camera->set_transform(t); @@ -603,19 +603,19 @@ void ARVROrigin::_notification(int p_what) { break; }; - // send our notification to all active ARVR interfaces, they may need to react to it also - for (int i = 0; i < arvr_server->get_interface_count(); i++) { - Ref<ARVRInterface> interface = arvr_server->get_interface(i); + // send our notification to all active XE interfaces, they may need to react to it also + for (int i = 0; i < xr_server->get_interface_count(); i++) { + Ref<XRInterface> interface = xr_server->get_interface(i); if (interface.is_valid() && interface->is_initialized()) { interface->notification(p_what); } } }; -ARVROrigin::ARVROrigin() { +XROrigin3D::XROrigin3D() { tracked_camera = nullptr; }; -ARVROrigin::~ARVROrigin(){ +XROrigin3D::~XROrigin3D(){ // nothing to do here yet for now.. }; diff --git a/scene/3d/arvr_nodes.h b/scene/3d/xr_nodes.h index bc5df2e174..a2f16545d1 100644 --- a/scene/3d/arvr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_nodes.h */ +/* xr_nodes.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,24 +28,24 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_NODES_H -#define ARVR_NODES_H +#ifndef XR_NODES_H +#define XR_NODES_H #include "scene/3d/camera_3d.h" #include "scene/3d/node_3d.h" #include "scene/resources/mesh.h" -#include "servers/arvr/arvr_positional_tracker.h" +#include "servers/xr/xr_positional_tracker.h" /** @author Bastiaan Olij <mux213@gmail.com> **/ /* - ARVRCamera is a subclass of camera which will register itself with its parent ARVROrigin and as a result is automatically positioned + XRCamera is a subclass of camera which will register itself with its parent XROrigin and as a result is automatically positioned */ -class ARVRCamera : public Camera3D { +class XRCamera3D : public Camera3D { - GDCLASS(ARVRCamera, Camera3D); + GDCLASS(XRCamera3D, Camera3D); protected: void _notification(int p_what); @@ -58,19 +58,19 @@ public: virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const; virtual Vector<Plane> get_frustum() const; - ARVRCamera(); - ~ARVRCamera(); + XRCamera3D(); + ~XRCamera3D(); }; /* - ARVRController is a helper node that automatically updates its position based on tracker data. + XRController3D is a helper node that automatically updates its position based on tracker data. - It must be a child node of our ARVROrigin node + It must be a child node of our XROrigin node */ -class ARVRController : public Node3D { +class XRController3D : public Node3D { - GDCLASS(ARVRController, Node3D); + GDCLASS(XRController3D, Node3D); private: int controller_id; @@ -95,23 +95,23 @@ public: void set_rumble(real_t p_rumble); bool get_is_active() const; - ARVRPositionalTracker::TrackerHand get_hand() const; + XRPositionalTracker::TrackerHand get_hand() const; Ref<Mesh> get_mesh(void) const; String get_configuration_warning() const; - ARVRController(); - ~ARVRController(); + XRController3D(); + ~XRController3D(); }; /* - ARVRAnchor is a helper node that automatically updates its position based on anchor data, it represents a real world location. - It must be a child node of our ARVROrigin node + XRAnchor3D is a helper node that automatically updates its position based on anchor data, it represents a real world location. + It must be a child node of our XROrigin3D node */ -class ARVRAnchor : public Node3D { - GDCLASS(ARVRAnchor, Node3D); +class XRAnchor3D : public Node3D { + GDCLASS(XRAnchor3D, Node3D); private: int anchor_id; @@ -137,24 +137,24 @@ public: String get_configuration_warning() const; - ARVRAnchor(); - ~ARVRAnchor(); + XRAnchor3D(); + ~XRAnchor3D(); }; /* - ARVROrigin is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world. + XROrigin3D is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world. It is this point that you will move around the world as the player 'moves while standing still', i.e. the player moves through teleporting or controller inputs as opposed to physically moving. Our camera and controllers will always be child nodes and thus place relative to this origin point. - This node will automatically locate any camera child nodes and update its position while our ARVRController node will handle tracked controllers. + This node will automatically locate any camera child nodes and update its position while our XRController3D node will handle tracked controllers. */ -class ARVROrigin : public Node3D { +class XROrigin3D : public Node3D { - GDCLASS(ARVROrigin, Node3D); + GDCLASS(XROrigin3D, Node3D); private: - ARVRCamera *tracked_camera; + XRCamera3D *tracked_camera; protected: void _notification(int p_what); @@ -163,14 +163,14 @@ protected: public: String get_configuration_warning() const; - void set_tracked_camera(ARVRCamera *p_tracked_camera); - void clear_tracked_camera_if(ARVRCamera *p_tracked_camera); + void set_tracked_camera(XRCamera3D *p_tracked_camera); + void clear_tracked_camera_if(XRCamera3D *p_tracked_camera); float get_world_scale() const; void set_world_scale(float p_world_scale); - ARVROrigin(); - ~ARVROrigin(); + XROrigin3D(); + ~XROrigin3D(); }; -#endif /* ARVR_NODES_H */ +#endif /* XR_NODES_H */ |