diff options
Diffstat (limited to 'scene/3d')
-rw-r--r-- | scene/3d/SCsub | 10 | ||||
-rw-r--r-- | scene/3d/area.cpp | 4 | ||||
-rw-r--r-- | scene/3d/audio_stream_player_3d.cpp | 149 | ||||
-rw-r--r-- | scene/3d/audio_stream_player_3d.h | 1 | ||||
-rw-r--r-- | scene/3d/collision_object.cpp | 2 | ||||
-rw-r--r-- | scene/3d/cpu_particles.cpp | 23 | ||||
-rw-r--r-- | scene/3d/cpu_particles.h | 4 | ||||
-rw-r--r-- | scene/3d/light.cpp | 5 | ||||
-rw-r--r-- | scene/3d/physics_body.cpp | 4 | ||||
-rw-r--r-- | scene/3d/sprite_3d.cpp | 36 | ||||
-rw-r--r-- | scene/3d/sprite_3d.h | 3 | ||||
-rw-r--r-- | scene/3d/vehicle_body.cpp | 68 | ||||
-rw-r--r-- | scene/3d/vehicle_body.h | 11 | ||||
-rw-r--r-- | scene/3d/visual_instance.cpp | 13 |
14 files changed, 231 insertions, 102 deletions
diff --git a/scene/3d/SCsub b/scene/3d/SCsub index 200cf4316f..31a443bad1 100644 --- a/scene/3d/SCsub +++ b/scene/3d/SCsub @@ -3,10 +3,10 @@ Import('env') if env['disable_3d']: - env.scene_sources.append("3d/spatial.cpp") - env.scene_sources.append("3d/skeleton.cpp") - env.scene_sources.append("3d/particles.cpp") - env.scene_sources.append("3d/visual_instance.cpp") - env.scene_sources.append("3d/world_environment.cpp") + env.add_source_files(env.scene_sources, "spatial.cpp") + env.add_source_files(env.scene_sources, "skeleton.cpp") + env.add_source_files(env.scene_sources, "particles.cpp") + env.add_source_files(env.scene_sources, "visual_instance.cpp") + env.add_source_files(env.scene_sources, "world_environment.cpp") else: env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 4247266e3d..19f43dd274 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -718,8 +718,8 @@ void Area::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_vec"), "set_gravity_vector", "get_gravity_vector"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_gravity", "get_gravity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), "set_linear_damp", "get_linear_damp"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index ff28f60d4f..27f16f7601 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -35,6 +35,99 @@ #include "scene/3d/listener.h" #include "scene/main/viewport.h" +// Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004) +// Speaker-Placement Correction Amplitude Panning (SPCAP) +class Spcap { +private: + struct Speaker { + Vector3 direction; + real_t effective_number_of_speakers; // precalculated + mutable real_t squared_gain; // temporary + }; + + PoolVector<Speaker> speakers; + +public: + Spcap(unsigned int speaker_count, const Vector3 *speaker_directions) { + this->speakers.resize(speaker_count); + PoolVector<Speaker>::Write w = this->speakers.write(); + for (unsigned int speaker_num = 0; speaker_num < speaker_count; speaker_num++) { + w[speaker_num].direction = speaker_directions[speaker_num]; + w[speaker_num].squared_gain = 0.0; + w[speaker_num].effective_number_of_speakers = 0.0; + for (unsigned int other_speaker_num = 0; other_speaker_num < speaker_count; other_speaker_num++) { + w[speaker_num].effective_number_of_speakers += 0.5 * (1.0 + w[speaker_num].direction.dot(w[other_speaker_num].direction)); + } + } + } + + unsigned int get_speaker_count() const { + return (unsigned int)this->speakers.size(); + } + + Vector3 get_speaker_direction(unsigned int index) const { + return this->speakers.read()[index].direction; + } + + void calculate(const Vector3 &source_direction, real_t tightness, unsigned int volume_count, real_t *volumes) const { + PoolVector<Speaker>::Read r = this->speakers.read(); + real_t sum_squared_gains = 0.0; + for (unsigned int speaker_num = 0; speaker_num < (unsigned int)this->speakers.size(); speaker_num++) { + real_t initial_gain = 0.5 * powf(1.0 + r[speaker_num].direction.dot(source_direction), tightness) / r[speaker_num].effective_number_of_speakers; + r[speaker_num].squared_gain = initial_gain * initial_gain; + sum_squared_gains += r[speaker_num].squared_gain; + } + + for (unsigned int speaker_num = 0; speaker_num < MIN(volume_count, (unsigned int)this->speakers.size()); speaker_num++) { + volumes[speaker_num] = sqrtf(r[speaker_num].squared_gain / sum_squared_gains); + } + } +}; + +//TODO: hardcoded main speaker directions for 2, 3.1, 5.1 and 7.1 setups - these are simplified and could also be made configurable +static const Vector3 speaker_directions[7] = { + Vector3(-1.0, 0.0, -1.0).normalized(), // front-left + Vector3(1.0, 0.0, -1.0).normalized(), // front-right + Vector3(0.0, 0.0, -1.0).normalized(), // center + Vector3(-1.0, 0.0, 1.0).normalized(), // rear-left + Vector3(1.0, 0.0, 1.0).normalized(), // rear-right + Vector3(-1.0, 0.0, 0.0).normalized(), // side-left + Vector3(1.0, 0.0, 0.0).normalized(), // side-right +}; + +void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tightness, AudioStreamPlayer3D::Output &output) { + unsigned int speaker_count; // only main speakers (no LFE) + switch (AudioServer::get_singleton()->get_speaker_mode()) { + default: //fallthrough + case AudioServer::SPEAKER_MODE_STEREO: speaker_count = 2; break; + case AudioServer::SPEAKER_SURROUND_31: speaker_count = 3; break; + case AudioServer::SPEAKER_SURROUND_51: speaker_count = 5; break; + case AudioServer::SPEAKER_SURROUND_71: speaker_count = 7; break; + } + + Spcap spcap(speaker_count, speaker_directions); //TODO: should only be created/recreated once the speaker mode / speaker positions changes + real_t volumes[7]; + spcap.calculate(source_dir, tightness, speaker_count, volumes); + + switch (AudioServer::get_singleton()->get_speaker_mode()) { + case AudioServer::SPEAKER_SURROUND_71: + output.vol[3].l = volumes[5]; // side-left + output.vol[3].r = volumes[6]; // side-right + //fallthrough + case AudioServer::SPEAKER_SURROUND_51: + output.vol[2].l = volumes[3]; // rear-left + output.vol[2].r = volumes[4]; // rear-right + //fallthrough + case AudioServer::SPEAKER_SURROUND_31: + output.vol[1].r = 1.0; // LFE - always full power + output.vol[1].l = volumes[2]; // center + //fallthrough + case AudioServer::SPEAKER_MODE_STEREO: + output.vol[0].r = volumes[1]; // front-right + output.vol[0].l = volumes[0]; // front-left + } +} + void AudioStreamPlayer3D::_mix_audio() { if (!stream_playback.is_valid() || !active || @@ -381,59 +474,11 @@ void AudioStreamPlayer3D::_notification(int p_what) { output.filter_gain = Math::db2linear(db_att); - Vector3 flat_pos = local_pos; - flat_pos.y = 0; - flat_pos.normalize(); + //TODO: The lower the second parameter (tightness) the more the sound will "enclose" the listener (more undirected / playing from + // speakers not facing the source) - this could be made distance dependent. + _calc_output_vol(local_pos.normalized(), 4.0, output); unsigned int cc = AudioServer::get_singleton()->get_channel_count(); - if (cc == 1) { - // Stereo pair - float c = flat_pos.x * 0.5 + 0.5; - - output.vol[0].l = 1.0 - c; - output.vol[0].r = c; - } else { - Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin; - float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative - float angle = Math::rad2deg(Math::acos(c)); - float av = angle * (flat_pos.x < 0 ? -1 : 1) / 180.0; - - if (cc >= 1) { - // Stereo pair - float fl = Math::abs(1.0 - Math::abs(-0.8 - av)); - float fr = Math::abs(1.0 - Math::abs(0.8 - av)); - - output.vol[0].l = fl; - output.vol[0].r = fr; - } - - if (cc >= 2) { - // Center pair - float center = 1.0 - Math::sin(Math::acos(c)); - - output.vol[1].l = center; - output.vol[1].r = center; - } - - if (cc >= 3) { - // Side pair - float sleft = Math::abs(1.0 - Math::abs(-0.4 - av)); - float sright = Math::abs(1.0 - Math::abs(0.4 - av)); - - output.vol[2].l = sleft; - output.vol[2].r = sright; - } - - if (cc >= 4) { - // Rear pair - float rleft = Math::abs(1.0 - Math::abs(-0.2 - av)); - float rright = Math::abs(1.0 - Math::abs(0.2 - av)); - - output.vol[3].l = rleft; - output.vol[3].r = rright; - } - } - for (unsigned int k = 0; k < cc; k++) { output.vol[k] *= multiplier; } @@ -974,7 +1019,7 @@ void AudioStreamPlayer3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db"); ADD_GROUP("Attenuation Filter", "attenuation_filter_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "50,50000,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_attenuation_filter_db", "get_attenuation_filter_db"); ADD_GROUP("Doppler", "doppler_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index 93954e758a..494aa70097 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -115,6 +115,7 @@ private: bool stream_paused_fade_out; StringName bus; + static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Output &output); void _mix_audio(); static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer3D *>(self)->_mix_audio(); } diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp index 9d3e2983c4..63301fc226 100644 --- a/scene/3d/collision_object.cpp +++ b/scene/3d/collision_object.cpp @@ -370,7 +370,7 @@ String CollisionObject::get_configuration_warning() const { String warning = Spatial::get_configuration_warning(); if (shapes.empty()) { - if (warning == String()) { + if (!warning.empty()) { warning += "\n\n"; } warning += TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape or CollisionPolygon as a child to define its shape."); diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 86b407b9e6..fc16bc36cb 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -92,6 +92,10 @@ void CPUParticles::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; } +void CPUParticles::set_lifetime_randomness(float p_random) { + + lifetime_randomness = p_random; +} void CPUParticles::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; @@ -130,6 +134,10 @@ float CPUParticles::get_randomness_ratio() const { return randomness_ratio; } +float CPUParticles::get_lifetime_randomness() const { + + return lifetime_randomness; +} bool CPUParticles::get_use_local_coordinates() const { @@ -583,6 +591,10 @@ void CPUParticles::_particles_process(float p_delta) { } } + if (p.time * (1.0 - explosiveness_ratio) > p.lifetime) { + restart = true; + } + if (restart) { if (!emitting) { @@ -636,6 +648,7 @@ void CPUParticles::_particles_process(float p_delta) { p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1) p.transform = Transform(); p.time = 0; + p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness); p.base_color = Color(1, 1, 1, 1); switch (emission_shape) { @@ -701,6 +714,8 @@ void CPUParticles::_particles_process(float p_delta) { } else if (!p.active) { continue; + } else if (p.time > p.lifetime) { + p.active = false; } else { uint32_t alt_seed = p.seed; @@ -1059,9 +1074,6 @@ void CPUParticles::_notification(int p_what) { _set_redraw(false); } - if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { - } - if (p_what == NOTIFICATION_INTERNAL_PROCESS) { if (particles.size() == 0 || !is_visible_in_tree()) { @@ -1221,6 +1233,7 @@ void CPUParticles::convert_from_particles(Node *p_particles) { set_emission_box_extents(material->get_emission_box_extents()); set_gravity(material->get_gravity()); + set_lifetime_randomness(material->get_lifetime_randomness()); #define CONVERT_PARAM(m_param) \ set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \ @@ -1255,6 +1268,7 @@ void CPUParticles::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &CPUParticles::set_pre_process_time); ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &CPUParticles::set_explosiveness_ratio); ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &CPUParticles::set_randomness_ratio); + ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "random"), &CPUParticles::set_lifetime_randomness); ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &CPUParticles::set_use_local_coordinates); ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &CPUParticles::set_fixed_fps); ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &CPUParticles::set_fractional_delta); @@ -1267,6 +1281,7 @@ void CPUParticles::_bind_methods() { ClassDB::bind_method(D_METHOD("get_pre_process_time"), &CPUParticles::get_pre_process_time); ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &CPUParticles::get_explosiveness_ratio); ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &CPUParticles::get_randomness_ratio); + ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &CPUParticles::get_lifetime_randomness); ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &CPUParticles::get_use_local_coordinates); ClassDB::bind_method(D_METHOD("get_fixed_fps"), &CPUParticles::get_fixed_fps); ClassDB::bind_method(D_METHOD("get_fractional_delta"), &CPUParticles::get_fractional_delta); @@ -1290,6 +1305,7 @@ void CPUParticles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); @@ -1472,6 +1488,7 @@ CPUParticles::CPUParticles() { set_pre_process_time(0); set_explosiveness_ratio(0); set_randomness_ratio(0); + set_lifetime_randomness(0); set_use_local_coordinates(true); set_draw_order(DRAW_ORDER_INDEX); diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index 517df8490d..71de56f59e 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -95,6 +95,7 @@ private: float hue_rot_rand; float anim_offset_rand; float time; + float lifetime; Color base_color; uint32_t seed; @@ -137,6 +138,7 @@ private: float pre_process_time; float explosiveness_ratio; float randomness_ratio; + float lifetime_randomness; float speed_scale; bool local_coords; int fixed_fps; @@ -200,6 +202,7 @@ public: void set_pre_process_time(float p_time); void set_explosiveness_ratio(float p_ratio); void set_randomness_ratio(float p_ratio); + void set_lifetime_randomness(float p_random); void set_visibility_aabb(const AABB &p_aabb); void set_use_local_coordinates(bool p_enable); void set_speed_scale(float p_scale); @@ -211,6 +214,7 @@ public: float get_pre_process_time() const; float get_explosiveness_ratio() const; float get_randomness_ratio() const; + float get_lifetime_randomness() const; AABB get_visibility_aabb() const; bool get_use_local_coordinates() const; float get_speed_scale() const; diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 4ef945ab8d..85ee925248 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -200,9 +200,6 @@ void Light::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { _update_visibility(); } - - if (p_what == NOTIFICATION_EXIT_TREE) { - } } void Light::set_editor_only(bool p_editor_only) { @@ -413,7 +410,7 @@ DirectionalLight::DirectionalLight() : set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8); set_param(PARAM_SHADOW_BIAS, 0.1); - set_param(PARAM_SHADOW_MAX_DISTANCE, 200); + set_param(PARAM_SHADOW_MAX_DISTANCE, 100); set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE); diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 2f8b2ecc5c..fa2bb300fa 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1044,10 +1044,10 @@ void RigidBody::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_GROUP("Angular", "angular_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 67c79d8b5a..fc5523633d 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -558,12 +558,15 @@ Rect2 Sprite3D::get_region_rect() const { void Sprite3D::set_frame(int p_frame) { - ERR_FAIL_INDEX(p_frame, vframes * hframes); + ERR_FAIL_INDEX(p_frame, int64_t(vframes) * hframes); if (frame != p_frame) frame = p_frame; _queue_update(); + + _change_notify("frame"); + _change_notify("frame_coords"); emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -572,6 +575,17 @@ int Sprite3D::get_frame() const { return frame; } +void Sprite3D::set_frame_coords(const Vector2 &p_coord) { + ERR_FAIL_INDEX(int(p_coord.x), vframes); + ERR_FAIL_INDEX(int(p_coord.y), hframes); + + set_frame(int(p_coord.y) * hframes + int(p_coord.x)); +} + +Vector2 Sprite3D::get_frame_coords() const { + return Vector2(frame % hframes, frame / hframes); +} + void Sprite3D::set_vframes(int p_amount) { ERR_FAIL_COND(p_amount < 1); @@ -628,10 +642,9 @@ Rect2 Sprite3D::get_item_rect() const { void Sprite3D::_validate_property(PropertyInfo &property) const { if (property.name == "frame") { - - property.hint = PROPERTY_HINT_SPRITE_FRAME; - + property.hint = PROPERTY_HINT_RANGE; property.hint_string = "0," + itos(vframes * hframes - 1) + ",1"; + property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS; } } @@ -649,6 +662,9 @@ void Sprite3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite3D::set_frame); ClassDB::bind_method(D_METHOD("get_frame"), &Sprite3D::get_frame); + ClassDB::bind_method(D_METHOD("set_frame_coords", "coords"), &Sprite3D::set_frame_coords); + ClassDB::bind_method(D_METHOD("get_frame_coords"), &Sprite3D::get_frame_coords); + ClassDB::bind_method(D_METHOD("set_vframes", "vframes"), &Sprite3D::set_vframes); ClassDB::bind_method(D_METHOD("get_vframes"), &Sprite3D::get_vframes); @@ -659,7 +675,8 @@ void Sprite3D::_bind_methods() { ADD_GROUP("Animation", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); ADD_GROUP("Region", "region_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); @@ -851,14 +868,11 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const { } if (property.name == "frame") { - property.hint = PROPERTY_HINT_RANGE; - - if (frames->has_animation(animation)) { + if (frames->has_animation(animation) && frames->get_frame_count(animation) > 1) { property.hint_string = "0," + itos(frames->get_frame_count(animation) - 1) + ",1"; - } else { - property.hint_string = "0,0,0"; } + property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS; } } @@ -1091,7 +1105,7 @@ void AnimatedSprite3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); } diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 0e086ef31e..5ae9b153f9 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -173,6 +173,9 @@ public: void set_frame(int p_frame); int get_frame() const; + void set_frame_coords(const Vector2 &p_row); + Vector2 get_frame_coords() const; + void set_vframes(int p_amount); int get_vframes() const; diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index 89e96e0227..98e68cfbda 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -272,6 +272,20 @@ void VehicleWheel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rpm"), &VehicleWheel::get_rpm); + ClassDB::bind_method(D_METHOD("set_engine_force", "engine_force"), &VehicleWheel::set_engine_force); + ClassDB::bind_method(D_METHOD("get_engine_force"), &VehicleWheel::get_engine_force); + + ClassDB::bind_method(D_METHOD("set_brake", "brake"), &VehicleWheel::set_brake); + ClassDB::bind_method(D_METHOD("get_brake"), &VehicleWheel::get_brake); + + ClassDB::bind_method(D_METHOD("set_steering", "steering"), &VehicleWheel::set_steering); + ClassDB::bind_method(D_METHOD("get_steering"), &VehicleWheel::get_steering); + + ADD_GROUP("Per-Wheel Motion", ""); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "engine_force", PROPERTY_HINT_RANGE, "0.00,1024.0,0.01,or_greater"), "set_engine_force", "get_engine_force"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "brake", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_brake", "get_brake"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "steering", PROPERTY_HINT_RANGE, "-180,180.0,0.01"), "set_steering", "get_steering"); + ADD_GROUP("VehicleBody Motion", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_traction"), "set_use_as_traction", "is_used_as_traction"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_steering"), "set_use_as_steering", "is_used_as_steering"); ADD_GROUP("Wheel", "wheel_"); @@ -288,6 +302,34 @@ void VehicleWheel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation"); } +void VehicleWheel::set_engine_force(float p_engine_force) { + + m_engineForce = p_engine_force; +} + +float VehicleWheel::get_engine_force() const { + + return m_engineForce; +} + +void VehicleWheel::set_brake(float p_brake) { + + m_brake = p_brake; +} +float VehicleWheel::get_brake() const { + + return m_brake; +} + +void VehicleWheel::set_steering(float p_steering) { + + m_steering = p_steering; +} +float VehicleWheel::get_steering() const { + + return m_steering; +} + void VehicleWheel::set_use_as_traction(bool p_enable) { engine_traction = p_enable; @@ -374,10 +416,7 @@ void VehicleBody::_update_wheel(int p_idx, PhysicsDirectBodyState *s) { Vector3 fwd = up.cross(right); fwd = fwd.normalized(); - //rotate around steering over de wheelAxleWS - real_t steering = wheel.steers ? m_steeringValue : 0.0; - - Basis steeringMat(up, steering); + Basis steeringMat(up, wheel.m_steering); Basis rotatingMat(right, wheel.m_rotation); @@ -723,12 +762,11 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) { real_t rollingFriction = 0.f; if (wheelInfo.m_raycastInfo.m_isInContact) { - if (engine_force != 0.f && wheelInfo.engine_traction) { - rollingFriction = -engine_force * s->get_step(); + if (wheelInfo.m_engineForce != 0.f) { + rollingFriction = -wheelInfo.m_engineForce * s->get_step(); } else { real_t defaultRollingFrictionImpulse = 0.f; - float cbrake = MAX(wheelInfo.m_brake, brake); - real_t maxImpulse = cbrake ? cbrake : defaultRollingFrictionImpulse; + real_t maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse; btVehicleWheelContactPoint contactPt(s, wheelInfo.m_raycastInfo.m_groundObject, wheelInfo.m_raycastInfo.m_contactPointWS, m_forwardWS[wheel], maxImpulse); rollingFriction = _calc_rolling_friction(contactPt); } @@ -886,6 +924,11 @@ void VehicleBody::_direct_state_changed(Object *p_state) { void VehicleBody::set_engine_force(float p_engine_force) { engine_force = p_engine_force; + for (int i = 0; i < wheels.size(); i++) { + VehicleWheel &wheelInfo = *wheels[i]; + if (wheelInfo.engine_traction) + wheelInfo.m_engineForce = p_engine_force; + } } float VehicleBody::get_engine_force() const { @@ -896,6 +939,10 @@ float VehicleBody::get_engine_force() const { void VehicleBody::set_brake(float p_brake) { brake = p_brake; + for (int i = 0; i < wheels.size(); i++) { + VehicleWheel &wheelInfo = *wheels[i]; + wheelInfo.m_brake = p_brake; + } } float VehicleBody::get_brake() const { @@ -905,6 +952,11 @@ float VehicleBody::get_brake() const { void VehicleBody::set_steering(float p_steering) { m_steeringValue = p_steering; + for (int i = 0; i < wheels.size(); i++) { + VehicleWheel &wheelInfo = *wheels[i]; + if (wheelInfo.steers) + wheelInfo.m_steering = p_steering; + } } float VehicleBody::get_steering() const { diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h index 9e3fe72282..914bfd54bd 100644 --- a/scene/3d/vehicle_body.h +++ b/scene/3d/vehicle_body.h @@ -70,7 +70,7 @@ class VehicleWheel : public Spatial { real_t m_deltaRotation; real_t m_rpm; real_t m_rollInfluence; - //real_t m_engineForce; + real_t m_engineForce; real_t m_brake; real_t m_clippedInvContactDotSuspension; @@ -137,6 +137,15 @@ public: float get_rpm() const; + void set_engine_force(float p_engine_force); + float get_engine_force() const; + + void set_brake(float p_brake); + float get_brake() const; + + void set_steering(float p_steering); + float get_steering() const; + String get_configuration_warning() const; VehicleWheel(); diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 5141c84803..d1de0c56a7 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -215,17 +215,6 @@ float GeometryInstance::get_lod_max_hysteresis() const { } void GeometryInstance::_notification(int p_what) { - - if (p_what == NOTIFICATION_ENTER_WORLD) { - - if (flags[FLAG_USE_BAKED_LIGHT]) { - } - - } else if (p_what == NOTIFICATION_EXIT_WORLD) { - - if (flags[FLAG_USE_BAKED_LIGHT]) { - } - } } void GeometryInstance::set_flag(Flags p_flag, bool p_value) { @@ -236,8 +225,6 @@ void GeometryInstance::set_flag(Flags p_flag, bool p_value) { flags[p_flag] = p_value; VS::get_singleton()->instance_geometry_set_flag(get_instance(), (VS::InstanceFlags)p_flag, p_value); - if (p_flag == FLAG_USE_BAKED_LIGHT) { - } } bool GeometryInstance::get_flag(Flags p_flag) const { |