diff options
Diffstat (limited to 'servers')
53 files changed, 815 insertions, 961 deletions
diff --git a/servers/arvr/arvr_interface.cpp b/servers/arvr/arvr_interface.cpp index 55707def7c..458459a843 100644 --- a/servers/arvr/arvr_interface.cpp +++ b/servers/arvr/arvr_interface.cpp @@ -43,7 +43,7 @@ void ARVRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tracking_status"), &ARVRInterface::get_tracking_status); - ClassDB::bind_method(D_METHOD("get_recommended_render_targetsize"), &ARVRInterface::get_recommended_render_targetsize); + ClassDB::bind_method(D_METHOD("get_render_targetsize"), &ARVRInterface::get_render_targetsize); ClassDB::bind_method(D_METHOD("is_stereo"), &ARVRInterface::is_stereo); ADD_GROUP("Interface", "interface_"); diff --git a/servers/arvr/arvr_interface.h b/servers/arvr/arvr_interface.h index 880f6e4595..1599c1a64f 100644 --- a/servers/arvr/arvr_interface.h +++ b/servers/arvr/arvr_interface.h @@ -103,7 +103,7 @@ public: /** rendering and internal **/ - virtual Size2 get_recommended_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */ + virtual Size2 get_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */ virtual bool is_stereo() = 0; /* returns true if this interface requires stereo rendering (for VR HMDs) or mono rendering (for mobile AR) */ virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */ virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */ diff --git a/servers/arvr/arvr_positional_tracker.cpp b/servers/arvr/arvr_positional_tracker.cpp index 4ecd7a3898..fc0270615c 100644 --- a/servers/arvr/arvr_positional_tracker.cpp +++ b/servers/arvr/arvr_positional_tracker.cpp @@ -52,6 +52,11 @@ void ARVRPositionalTracker::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &ARVRPositionalTracker::set_joy_id); ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &ARVRPositionalTracker::set_orientation); ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &ARVRPositionalTracker::set_rw_position); + + ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRPositionalTracker::get_rumble); + ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRPositionalTracker::set_rumble); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "rumble"), "set_rumble", "get_rumble"); }; void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) { @@ -170,6 +175,18 @@ Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) return new_transform; }; +real_t ARVRPositionalTracker::get_rumble() const { + return rumble; +}; + +void ARVRPositionalTracker::set_rumble(real_t p_rumble) { + if (p_rumble > 0.0) { + rumble = p_rumble; + } else { + rumble = 0.0; + }; +}; + ARVRPositionalTracker::ARVRPositionalTracker() { type = ARVRServer::TRACKER_UNKNOWN; name = "Unknown"; @@ -178,6 +195,7 @@ ARVRPositionalTracker::ARVRPositionalTracker() { tracks_orientation = false; tracks_position = false; hand = TRACKER_HAND_UNKNOWN; + rumble = 0.0; }; ARVRPositionalTracker::~ARVRPositionalTracker(){ diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/arvr/arvr_positional_tracker.h index ff0c150f89..e450328a22 100644 --- a/servers/arvr/arvr_positional_tracker.h +++ b/servers/arvr/arvr_positional_tracker.h @@ -65,6 +65,7 @@ private: bool tracks_position; // do we track position? Vector3 rw_position; // our position "in the real world, so without world_scale applied" TrackerHand hand; // if known, the hand this tracker is held in + real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, arvr_interface is responsible for execution protected: static void _bind_methods(); @@ -87,6 +88,8 @@ public: Vector3 get_rw_position() const; ARVRPositionalTracker::TrackerHand get_hand() const; void set_hand(const ARVRPositionalTracker::TrackerHand p_hand); + real_t get_rumble() const; + void set_rumble(real_t p_rumble); Transform get_transform(bool p_adjust_by_reference_frame) const; diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp index ede080b424..1e73d6753c 100644 --- a/servers/arvr_server.cpp +++ b/servers/arvr_server.cpp @@ -49,15 +49,13 @@ void ARVRServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_interface_count"), &ARVRServer::get_interface_count); ClassDB::bind_method(D_METHOD("get_interface", "idx"), &ARVRServer::get_interface); + ClassDB::bind_method(D_METHOD("get_interfaces"), &ARVRServer::get_interfaces); ClassDB::bind_method(D_METHOD("find_interface", "name"), &ARVRServer::find_interface); ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count); ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker); ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface); - ClassDB::bind_method(D_METHOD("add_interface", "interface"), &ARVRServer::add_interface); - ClassDB::bind_method(D_METHOD("remove_interface", "interface"), &ARVRServer::remove_interface); - BIND_ENUM_CONSTANT(TRACKER_CONTROLLER); BIND_ENUM_CONSTANT(TRACKER_BASESTATION); BIND_ENUM_CONSTANT(TRACKER_ANCHOR); @@ -191,6 +189,21 @@ Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const { return interfaces[idx]; }; +Array ARVRServer::get_interfaces() const { + Array ret; + + for (int i = 0; i < interfaces.size(); i++) { + Dictionary iface_info; + + iface_info["id"] = i; + iface_info["name"] = interfaces[i]->get_name(); + + ret.push_back(iface_info); + }; + + return ret; +}; + /* A little extra info on the tracker ids, these are unique per tracker type so we get soem consistency in recognising our trackers, specifically controllers. diff --git a/servers/arvr_server.h b/servers/arvr_server.h index 948895cb27..9b84ee2e99 100644 --- a/servers/arvr_server.h +++ b/servers/arvr_server.h @@ -137,6 +137,7 @@ public: int get_interface_count() const; Ref<ARVRInterface> get_interface(int p_index) const; Ref<ARVRInterface> find_interface(const String &p_name) const; + Array get_interfaces() const; /* note, more then one interface can technically be active, especially on mobile, but only one interface is used for diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp index 113e356612..b0b94a1f49 100644 --- a/servers/audio/audio_rb_resampler.cpp +++ b/servers/audio/audio_rb_resampler.cpp @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "audio_rb_resampler.h" +#include "core/math/math_funcs.h" +#include "os/os.h" +#include "servers/audio_server.h" int AudioRBResampler::get_channel_count() const { @@ -37,8 +40,11 @@ int AudioRBResampler::get_channel_count() const { return channels; } +// Linear interpolation based sample rate convertion (low quality) +// Note that AudioStreamPlaybackResampled::mix has better algorithm, +// but it wasn't obvious to integrate that with VideoPlayer template <int C> -uint32_t AudioRBResampler::_resample(int32_t *p_dest, int p_todo, int32_t p_increment) { +uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) { uint32_t read = offset & MIX_FRAC_MASK; @@ -47,186 +53,128 @@ uint32_t AudioRBResampler::_resample(int32_t *p_dest, int p_todo, int32_t p_incr offset = (offset + p_increment) & (((1 << (rb_bits + MIX_FRAC_BITS)) - 1)); read += p_increment; uint32_t pos = offset >> MIX_FRAC_BITS; - uint32_t frac = offset & MIX_FRAC_MASK; -#ifndef FAST_AUDIO + float frac = float(offset & MIX_FRAC_MASK) / float(MIX_FRAC_LEN); ERR_FAIL_COND_V(pos >= rb_len, 0); -#endif uint32_t pos_next = (pos + 1) & rb_mask; - //printf("rb pos %i\n",pos); // since this is a template with a known compile time value (C), conditionals go away when compiling. if (C == 1) { - int32_t v0 = rb[pos]; - int32_t v0n = rb[pos_next]; -#ifndef FAST_AUDIO - v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS; -#endif - v0 <<= 16; - p_dest[i] = v0; + float v0 = rb[pos]; + float v0n = rb[pos_next]; + v0 += (v0n - v0) * frac; + p_dest[i] = AudioFrame(v0, v0); } + if (C == 2) { - int32_t v0 = rb[(pos << 1) + 0]; - int32_t v1 = rb[(pos << 1) + 1]; - int32_t v0n = rb[(pos_next << 1) + 0]; - int32_t v1n = rb[(pos_next << 1) + 1]; - -#ifndef FAST_AUDIO - v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS; - v1 += (v1n - v1) * (int32_t)frac >> MIX_FRAC_BITS; -#endif - v0 <<= 16; - v1 <<= 16; - p_dest[(i << 1) + 0] = v0; - p_dest[(i << 1) + 1] = v1; + float v0 = rb[(pos << 1) + 0]; + float v1 = rb[(pos << 1) + 1]; + float v0n = rb[(pos_next << 1) + 0]; + float v1n = rb[(pos_next << 1) + 1]; + + v0 += (v0n - v0) * frac; + v1 += (v1n - v1) * frac; + p_dest[i] = AudioFrame(v0, v1); } + // For now, channels higher than stereo are almost ignored if (C == 4) { - int32_t v0 = rb[(pos << 2) + 0]; - int32_t v1 = rb[(pos << 2) + 1]; - int32_t v2 = rb[(pos << 2) + 2]; - int32_t v3 = rb[(pos << 2) + 3]; - int32_t v0n = rb[(pos_next << 2) + 0]; - int32_t v1n = rb[(pos_next << 2) + 1]; - int32_t v2n = rb[(pos_next << 2) + 2]; - int32_t v3n = rb[(pos_next << 2) + 3]; - -#ifndef FAST_AUDIO - v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS; - v1 += (v1n - v1) * (int32_t)frac >> MIX_FRAC_BITS; - v2 += (v2n - v2) * (int32_t)frac >> MIX_FRAC_BITS; - v3 += (v3n - v3) * (int32_t)frac >> MIX_FRAC_BITS; -#endif - v0 <<= 16; - v1 <<= 16; - v2 <<= 16; - v3 <<= 16; - p_dest[(i << 2) + 0] = v0; - p_dest[(i << 2) + 1] = v1; - p_dest[(i << 2) + 2] = v2; - p_dest[(i << 2) + 3] = v3; + float v0 = rb[(pos << 2) + 0]; + float v1 = rb[(pos << 2) + 1]; + float v2 = rb[(pos << 2) + 2]; + float v3 = rb[(pos << 2) + 3]; + float v0n = rb[(pos_next << 2) + 0]; + float v1n = rb[(pos_next << 2) + 1]; + float v2n = rb[(pos_next << 2) + 2]; + float v3n = rb[(pos_next << 2) + 3]; + + v0 += (v0n - v0) * frac; + v1 += (v1n - v1) * frac; + v2 += (v2n - v2) * frac; + v3 += (v3n - v3) * frac; + p_dest[i] = AudioFrame(v0, v1); } if (C == 6) { - int32_t v0 = rb[(pos * 6) + 0]; - int32_t v1 = rb[(pos * 6) + 1]; - int32_t v2 = rb[(pos * 6) + 2]; - int32_t v3 = rb[(pos * 6) + 3]; - int32_t v4 = rb[(pos * 6) + 4]; - int32_t v5 = rb[(pos * 6) + 5]; - int32_t v0n = rb[(pos_next * 6) + 0]; - int32_t v1n = rb[(pos_next * 6) + 1]; - int32_t v2n = rb[(pos_next * 6) + 2]; - int32_t v3n = rb[(pos_next * 6) + 3]; - int32_t v4n = rb[(pos_next * 6) + 4]; - int32_t v5n = rb[(pos_next * 6) + 5]; - -#ifndef FAST_AUDIO - v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS; - v1 += (v1n - v1) * (int32_t)frac >> MIX_FRAC_BITS; - v2 += (v2n - v2) * (int32_t)frac >> MIX_FRAC_BITS; - v3 += (v3n - v3) * (int32_t)frac >> MIX_FRAC_BITS; - v4 += (v4n - v4) * (int32_t)frac >> MIX_FRAC_BITS; - v5 += (v5n - v5) * (int32_t)frac >> MIX_FRAC_BITS; -#endif - v0 <<= 16; - v1 <<= 16; - v2 <<= 16; - v3 <<= 16; - v4 <<= 16; - v5 <<= 16; - p_dest[(i * 6) + 0] = v0; - p_dest[(i * 6) + 1] = v1; - p_dest[(i * 6) + 2] = v2; - p_dest[(i * 6) + 3] = v3; - p_dest[(i * 6) + 4] = v4; - p_dest[(i * 6) + 5] = v5; + float v0 = rb[(pos * 6) + 0]; + float v1 = rb[(pos * 6) + 1]; + float v2 = rb[(pos * 6) + 2]; + float v3 = rb[(pos * 6) + 3]; + float v4 = rb[(pos * 6) + 4]; + float v5 = rb[(pos * 6) + 5]; + float v0n = rb[(pos_next * 6) + 0]; + float v1n = rb[(pos_next * 6) + 1]; + float v2n = rb[(pos_next * 6) + 2]; + float v3n = rb[(pos_next * 6) + 3]; + float v4n = rb[(pos_next * 6) + 4]; + float v5n = rb[(pos_next * 6) + 5]; + + p_dest[i] = AudioFrame(v0, v1); } } - return read >> MIX_FRAC_BITS; //rb_read_pos=offset>>MIX_FRAC_BITS; + return read >> MIX_FRAC_BITS; //rb_read_pos = offset >> MIX_FRAC_BITS; } -bool AudioRBResampler::mix(int32_t *p_dest, int p_frames) { +bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) { if (!rb) return false; - int write_pos_cache = rb_write_pos; - int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate; - - int rb_todo; - - if (write_pos_cache == rb_read_pos) { - return false; //out of buffer - - } else if (rb_read_pos < write_pos_cache) { - - rb_todo = write_pos_cache - rb_read_pos; //-1? - } else { - - rb_todo = (rb_len - rb_read_pos) + write_pos_cache; //-1? - } - - int todo = MIN(((int64_t(rb_todo) << MIX_FRAC_BITS) / increment) + 1, p_frames); + int read_space = get_reader_space(); + int target_todo = MIN(get_num_of_ready_frames(), p_frames); { - - int read = 0; + int src_read = 0; switch (channels) { - case 1: read = _resample<1>(p_dest, todo, increment); break; - case 2: read = _resample<2>(p_dest, todo, increment); break; - case 4: read = _resample<4>(p_dest, todo, increment); break; - case 6: read = _resample<6>(p_dest, todo, increment); break; + case 1: src_read = _resample<1>(p_dest, target_todo, increment); break; + case 2: src_read = _resample<2>(p_dest, target_todo, increment); break; + case 4: src_read = _resample<4>(p_dest, target_todo, increment); break; + case 6: src_read = _resample<6>(p_dest, target_todo, increment); break; } - //end of stream, fadeout - int remaining = p_frames - todo; - if (remaining && todo > 0) { - - //print_line("fadeout"); - for (uint32_t c = 0; c < channels; c++) { + if (src_read > read_space) + src_read = read_space; - for (int i = 0; i < todo; i++) { + rb_read_pos = (rb_read_pos + src_read) & rb_mask; - int32_t samp = p_dest[i * channels + c] >> 8; - uint32_t mul = (todo - i) * 256 / todo; - //print_line("mul: "+itos(i)+" "+itos(mul)); - p_dest[i * channels + c] = samp * mul; - } + // Create fadeout effect for the end of stream (note that it can be because of slow writer) + if (p_frames - target_todo > 0) { + for (int i = 0; i < target_todo; i++) { + p_dest[i] = p_dest[i] * float(target_todo - i) / float(target_todo); } } - //zero out what remains there to avoid glitches - for (uint32_t i = todo * channels; i < int(p_frames) * channels; i++) { - - p_dest[i] = 0; + // Fill zeros (silence) for the rest of frames + for (uint32_t i = target_todo; i < p_frames; i++) { + p_dest[i] = AudioFrame(0, 0); } - - if (read > rb_todo) - read = rb_todo; - - rb_read_pos = (rb_read_pos + read) & rb_mask; } return true; } +int AudioRBResampler::get_num_of_ready_frames() { + if (!is_ready()) + return 0; + int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate; + int read_space = get_reader_space(); + return (int64_t(read_space) << MIX_FRAC_BITS) / increment; +} + Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed) { ERR_FAIL_COND_V(p_channels != 1 && p_channels != 2 && p_channels != 4 && p_channels != 6, ERR_INVALID_PARAMETER); - //float buffering_sec = int(GLOBAL_DEF("audio/stream_buffering_ms",500))/1000.0; int desired_rb_bits = nearest_shift(MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed)); bool recreate = !rb; if (rb && (uint32_t(desired_rb_bits) != rb_bits || channels != uint32_t(p_channels))) { - //recreate memdelete_arr(rb); memdelete_arr(read_buf); @@ -239,8 +187,8 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m rb_bits = desired_rb_bits; rb_len = (1 << rb_bits); rb_mask = rb_len - 1; - rb = memnew_arr(int16_t, rb_len * p_channels); - read_buf = memnew_arr(int16_t, rb_len * p_channels); + rb = memnew_arr(float, rb_len *p_channels); + read_buf = memnew_arr(float, rb_len *p_channels); } src_mix_rate = p_src_mix_rate; diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h index bc1f924ab5..08c7a5a668 100644 --- a/servers/audio/audio_rb_resampler.h +++ b/servers/audio/audio_rb_resampler.h @@ -31,6 +31,7 @@ #define AUDIO_RB_RESAMPLER_H #include "os/memory.h" +#include "servers/audio_server.h" #include "typedefs.h" struct AudioRBResampler { @@ -53,11 +54,11 @@ struct AudioRBResampler { MIX_FRAC_MASK = MIX_FRAC_LEN - 1, }; - int16_t *read_buf; - int16_t *rb; + float *read_buf; + float *rb; template <int C> - uint32_t _resample(int32_t *p_dest, int p_todo, int32_t p_increment); + uint32_t _resample(AudioFrame *p_dest, int p_todo, int32_t p_increment); public: _FORCE_INLINE_ void flush() { @@ -71,33 +72,48 @@ public: } _FORCE_INLINE_ int get_total() const { - return rb_len - 1; } - _FORCE_INLINE_ int get_todo() const { //return amount of frames to mix - - int todo; - int read_pos_cache = rb_read_pos; + _FORCE_INLINE_ int get_writer_space() const { + int space, r, w; - if (read_pos_cache == rb_write_pos) { - todo = rb_len - 1; - } else if (read_pos_cache > rb_write_pos) { + r = rb_read_pos; + w = rb_write_pos; - todo = read_pos_cache - rb_write_pos - 1; + if (r == w) { + space = rb_len - 1; + } else if (w < r) { + space = r - w - 1; } else { + space = (rb_len - r) + w - 1; + } + + return space; + } + + _FORCE_INLINE_ int get_reader_space() const { + int space, r, w; - todo = (rb_len - rb_write_pos) + read_pos_cache - 1; + r = rb_read_pos; + w = rb_write_pos; + + if (r == w) { + space = 0; + } else if (w < r) { + space = rb_len - r + w; + } else { + space = w - r; } - return todo; + return space; } _FORCE_INLINE_ bool has_data() const { return rb && rb_read_pos != rb_write_pos; } - _FORCE_INLINE_ int16_t *get_write_buffer() { return read_buf; } + _FORCE_INLINE_ float *get_write_buffer() { return read_buf; } _FORCE_INLINE_ void write(uint32_t p_frames) { ERR_FAIL_COND(p_frames >= rb_len); @@ -151,7 +167,8 @@ public: Error setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed = -1); void clear(); - bool mix(int32_t *p_dest, int p_frames); + bool mix(AudioFrame *p_dest, int p_frames); + int get_num_of_ready_frames(); AudioRBResampler(); ~AudioRBResampler(); diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 0e3d5824d9..d7b2c2c5e0 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -191,12 +191,12 @@ void AudioStreamPlaybackRandomPitch::seek(float p_time) { } } -void AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames) { +void AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { if (playing.is_valid()) { - playing->mix(p_bufer, p_rate_scale * pitch_scale, p_frames); + playing->mix(p_buffer, p_rate_scale * pitch_scale, p_frames); } else { for (int i = 0; i < p_frames; i++) { - p_bufer[i] = AudioFrame(0, 0); + p_buffer[i] = AudioFrame(0, 0); } } } diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 3324597b41..dc931502b4 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -48,7 +48,7 @@ public: virtual float get_playback_position() const = 0; virtual void seek(float p_time) = 0; - virtual void mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames) = 0; + virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) = 0; virtual float get_length() const = 0; //if supported, otherwise return 0 }; @@ -70,7 +70,7 @@ class AudioStreamPlaybackResampled : public AudioStreamPlayback { protected: void _begin_resample(); - virtual void _mix_internal(AudioFrame *p_bufer, int p_frames) = 0; + virtual void _mix_internal(AudioFrame *p_buffer, int p_frames) = 0; virtual float get_stream_sampling_rate() = 0; public: @@ -136,7 +136,7 @@ public: virtual float get_playback_position() const; virtual void seek(float p_time); - virtual void mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames); + virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames); virtual float get_length() const; //if supported, otherwise return 0 diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 18b7014595..6a10d7539d 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -226,7 +226,7 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { static int total = 0; ticks = OS::get_singleton()->get_ticks_msec(); - if ((ticks - first_ticks) > 10 * 1000) { + if ((ticks - first_ticks) > 10 * 1000 && count > 0) { print_line("Audio Driver " + String(AudioDriver::get_singleton()->get_name()) + " average latency: " + itos(total / count) + "ms (frame=" + itos(p_frames) + ")"); first_ticks = ticks; total = 0; @@ -876,6 +876,8 @@ void AudioServer::init() { #ifdef TOOLS_ENABLED set_edited(false); //avoid editors from thinking this was edited #endif + + GLOBAL_DEF("audio/video_delay_compensation_ms", 0); } void AudioServer::load_default_bus_layout() { diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index a289b4b0ca..ef54eb58cf 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -46,6 +46,7 @@ //#define ALLOWED_PENETRATION 0.01 #define RELAXATION_TIMESTEPS 3 #define MIN_VELOCITY 0.0001 +#define MAX_BIAS_ROTATION (Math_PI / 8) void BodyPairSW::_contact_added_callback(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) { @@ -71,6 +72,7 @@ void BodyPairSW::contact_added_callback(const Vector3 &p_point_A, const Vector3 contact.acc_normal_impulse = 0; contact.acc_bias_impulse = 0; + contact.acc_bias_impulse_center_of_mass = 0; contact.acc_tangent_impulse = Vector3(); contact.local_A = local_A; contact.local_B = local_B; @@ -82,12 +84,12 @@ void BodyPairSW::contact_added_callback(const Vector3 &p_point_A, const Vector3 for (int i = 0; i < contact_count; i++) { Contact &c = contacts[i]; - if ( - c.local_A.distance_squared_to(local_A) < (contact_recycle_radius * contact_recycle_radius) && + if (c.local_A.distance_squared_to(local_A) < (contact_recycle_radius * contact_recycle_radius) && c.local_B.distance_squared_to(local_B) < (contact_recycle_radius * contact_recycle_radius)) { contact.acc_normal_impulse = c.acc_normal_impulse; contact.acc_bias_impulse = c.acc_bias_impulse; + contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass; contact.acc_tangent_impulse = c.acc_tangent_impulse; new_index = i; break; @@ -325,9 +327,7 @@ bool BodyPairSW::setup(real_t p_step) { A->apply_impulse(c.rA + A->get_center_of_mass(), -j_vec); B->apply_impulse(c.rB + B->get_center_of_mass(), j_vec); c.acc_bias_impulse = 0; - Vector3 jb_vec = c.normal * c.acc_bias_impulse; - A->apply_bias_impulse(c.rA + A->get_center_of_mass(), -jb_vec); - B->apply_bias_impulse(c.rB + B->get_center_of_mass(), jb_vec); + c.acc_bias_impulse_center_of_mass = 0; c.bounce = MAX(A->get_bounce(), B->get_bounce()); if (c.bounce) { @@ -356,7 +356,7 @@ void BodyPairSW::solve(real_t p_step) { c.active = false; //try to deactivate, will activate itself if still needed - //bias impule + //bias impulse Vector3 crbA = A->get_biased_angular_velocity().cross(c.rA); Vector3 crbB = B->get_biased_angular_velocity().cross(c.rB); @@ -372,8 +372,26 @@ void BodyPairSW::solve(real_t p_step) { Vector3 jb = c.normal * (c.acc_bias_impulse - jbnOld); - A->apply_bias_impulse(c.rA + A->get_center_of_mass(), -jb); - B->apply_bias_impulse(c.rB + B->get_center_of_mass(), jb); + A->apply_bias_impulse(c.rA + A->get_center_of_mass(), -jb, MAX_BIAS_ROTATION / p_step); + B->apply_bias_impulse(c.rB + B->get_center_of_mass(), jb, MAX_BIAS_ROTATION / p_step); + + crbA = A->get_biased_angular_velocity().cross(c.rA); + crbB = B->get_biased_angular_velocity().cross(c.rB); + dbv = B->get_biased_linear_velocity() + crbB - A->get_biased_linear_velocity() - crbA; + + vbn = dbv.dot(c.normal); + + if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) { + + real_t jbn_com = (-vbn + c.bias) / (A->get_inv_mass() + B->get_inv_mass()); + real_t jbnOld_com = c.acc_bias_impulse_center_of_mass; + c.acc_bias_impulse_center_of_mass = MAX(jbnOld_com + jbn_com, 0.0f); + + Vector3 jb_com = c.normal * (c.acc_bias_impulse_center_of_mass - jbnOld_com); + + A->apply_bias_impulse(A->get_center_of_mass(), -jb_com, 0.0f); + B->apply_bias_impulse(B->get_center_of_mass(), jb_com, 0.0f); + } c.active = true; } @@ -382,7 +400,7 @@ void BodyPairSW::solve(real_t p_step) { Vector3 crB = B->get_angular_velocity().cross(c.rB); Vector3 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA; - //normal impule + //normal impulse real_t vn = dv.dot(c.normal); if (Math::abs(vn) > MIN_VELOCITY) { @@ -399,7 +417,7 @@ void BodyPairSW::solve(real_t p_step) { c.active = true; } - //friction impule + //friction impulse real_t friction = A->get_friction() * B->get_friction(); diff --git a/servers/physics/body_pair_sw.h b/servers/physics/body_pair_sw.h index f09c977950..74fda60998 100644 --- a/servers/physics/body_pair_sw.h +++ b/servers/physics/body_pair_sw.h @@ -59,6 +59,7 @@ class BodyPairSW : public ConstraintSW { real_t acc_normal_impulse; // accumulated normal impulse (Pn) Vector3 acc_tangent_impulse; // accumulated tangent impulse (Pt) real_t acc_bias_impulse; // accumulated normal impulse for position bias (Pnb) + real_t acc_bias_impulse_center_of_mass; // accumulated normal impulse for position bias applied to com real_t mass_normal; real_t bias; real_t bounce; diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 46a5192e52..f8cd6ca858 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -45,8 +45,9 @@ void BodySW::_update_transform_dependant() { // update inertia tensor Basis tb = principal_inertia_axes; Basis tbt = tb.transposed(); - tb.scale(_inv_inertia); - _inv_inertia_tensor = tb * tbt; + Basis diag; + diag.scale(_inv_inertia); + _inv_inertia_tensor = tb * diag * tbt; } void BodySW::update_inertias() { @@ -735,6 +736,10 @@ void BodySW::set_force_integration_callback(ObjectID p_id, const StringName &p_m } } +void BodySW::set_kinematic_margin(real_t p_margin) { + kinematic_safe_margin = p_margin; +} + BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_update_list(this), direct_state_query_list(this) { @@ -742,6 +747,7 @@ BodySW::BodySW() active = true; mass = 1; + kinematic_safe_margin = 0.01; //_inv_inertia=Transform(); _inv_mass = 1; bounce = 0; diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h index 782bf14a4b..738d99c764 100644 --- a/servers/physics/body_sw.h +++ b/servers/physics/body_sw.h @@ -55,6 +55,7 @@ class BodySW : public CollisionObjectSW { PhysicsServer::BodyAxisLock axis_lock; + real_t kinematic_safe_margin; real_t _inv_mass; Vector3 _inv_inertia; // Relative to the principal axes of inertia @@ -149,6 +150,9 @@ class BodySW : public CollisionObjectSW { public: void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant()); + void set_kinematic_margin(real_t p_margin); + _FORCE_INLINE_ real_t get_kinematic_margin() { return kinematic_safe_margin; } + _FORCE_INLINE_ void add_area(AreaSW *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { @@ -223,10 +227,16 @@ public: angular_velocity += _inv_inertia_tensor.xform(p_j); } - _FORCE_INLINE_ void apply_bias_impulse(const Vector3 &p_pos, const Vector3 &p_j) { + _FORCE_INLINE_ void apply_bias_impulse(const Vector3 &p_pos, const Vector3 &p_j, real_t p_max_delta_av = -1.0) { biased_linear_velocity += p_j * _inv_mass; - biased_angular_velocity += _inv_inertia_tensor.xform((p_pos - center_of_mass).cross(p_j)); + if (p_max_delta_av != 0.0) { + Vector3 delta_av = _inv_inertia_tensor.xform((p_pos - center_of_mass).cross(p_j)); + if (p_max_delta_av > 0 && delta_av.length() > p_max_delta_av) { + delta_av = delta_av.normalized() * p_max_delta_av; + } + biased_angular_velocity += delta_av; + } } _FORCE_INLINE_ void apply_bias_torque_impulse(const Vector3 &p_j) { diff --git a/servers/physics/broad_phase_basic.cpp b/servers/physics/broad_phase_basic.cpp index c6565ac2e9..e4eae09c61 100644 --- a/servers/physics/broad_phase_basic.cpp +++ b/servers/physics/broad_phase_basic.cpp @@ -46,7 +46,7 @@ BroadPhaseSW::ID BroadPhaseBasic::create(CollisionObjectSW *p_object, int p_subi return current; } -void BroadPhaseBasic::move(ID p_id, const Rect3 &p_aabb) { +void BroadPhaseBasic::move(ID p_id, const AABB &p_aabb) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); @@ -109,7 +109,7 @@ int BroadPhaseBasic::cull_point(const Vector3 &p_point, CollisionObjectSW **p_re for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect3 aabb = E->get().aabb; + const AABB aabb = E->get().aabb; if (aabb.has_point(p_point)) { p_results[rc] = E->get().owner; @@ -129,7 +129,7 @@ int BroadPhaseBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, Co for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect3 aabb = E->get().aabb; + const AABB aabb = E->get().aabb; if (aabb.intersects_segment(p_from, p_to)) { p_results[rc] = E->get().owner; @@ -142,13 +142,13 @@ int BroadPhaseBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, Co return rc; } -int BroadPhaseBasic::cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { +int BroadPhaseBasic::cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect3 aabb = E->get().aabb; + const AABB aabb = E->get().aabb; if (aabb.intersects(p_aabb)) { p_results[rc] = E->get().owner; diff --git a/servers/physics/broad_phase_basic.h b/servers/physics/broad_phase_basic.h index 5c124c1792..ee683ed840 100644 --- a/servers/physics/broad_phase_basic.h +++ b/servers/physics/broad_phase_basic.h @@ -39,7 +39,7 @@ class BroadPhaseBasic : public BroadPhaseSW { CollisionObjectSW *owner; bool _static; - Rect3 aabb; + AABB aabb; int subindex; }; @@ -83,7 +83,7 @@ class BroadPhaseBasic : public BroadPhaseSW { public: // 0 is an invalid ID virtual ID create(CollisionObjectSW *p_object, int p_subindex = 0); - virtual void move(ID p_id, const Rect3 &p_aabb); + virtual void move(ID p_id, const AABB &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); @@ -93,7 +93,7 @@ public: virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics/broad_phase_octree.cpp b/servers/physics/broad_phase_octree.cpp index e7111d9580..3b18a270f0 100644 --- a/servers/physics/broad_phase_octree.cpp +++ b/servers/physics/broad_phase_octree.cpp @@ -32,11 +32,11 @@ BroadPhaseSW::ID BroadPhaseOctree::create(CollisionObjectSW *p_object, int p_subindex) { - ID oid = octree.create(p_object, Rect3(), p_subindex, false, 1 << p_object->get_type(), 0); + ID oid = octree.create(p_object, AABB(), p_subindex, false, 1 << p_object->get_type(), 0); return oid; } -void BroadPhaseOctree::move(ID p_id, const Rect3 &p_aabb) { +void BroadPhaseOctree::move(ID p_id, const AABB &p_aabb) { octree.move(p_id, p_aabb); } @@ -76,7 +76,7 @@ int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, C return octree.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); } -int BroadPhaseOctree::cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { +int BroadPhaseOctree::cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { return octree.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); } diff --git a/servers/physics/broad_phase_octree.h b/servers/physics/broad_phase_octree.h index d28f2da13f..f894d6ca5a 100644 --- a/servers/physics/broad_phase_octree.h +++ b/servers/physics/broad_phase_octree.h @@ -48,7 +48,7 @@ class BroadPhaseOctree : public BroadPhaseSW { public: // 0 is an invalid ID virtual ID create(CollisionObjectSW *p_object, int p_subindex = 0); - virtual void move(ID p_id, const Rect3 &p_aabb); + virtual void move(ID p_id, const AABB &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); @@ -58,7 +58,7 @@ public: virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics/broad_phase_sw.h b/servers/physics/broad_phase_sw.h index 2b5ed629fe..5ad3f9a261 100644 --- a/servers/physics/broad_phase_sw.h +++ b/servers/physics/broad_phase_sw.h @@ -30,8 +30,8 @@ #ifndef BROAD_PHASE_SW_H #define BROAD_PHASE_SW_H +#include "aabb.h" #include "math_funcs.h" -#include "rect3.h" class CollisionObjectSW; @@ -49,7 +49,7 @@ public: // 0 is an invalid ID virtual ID create(CollisionObjectSW *p_object_, int p_subindex = 0) = 0; - virtual void move(ID p_id, const Rect3 &p_aabb) = 0; + virtual void move(ID p_id, const AABB &p_aabb) = 0; virtual void set_static(ID p_id, bool p_static) = 0; virtual void remove(ID p_id) = 0; @@ -59,7 +59,7 @@ public: virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; - virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; + virtual int cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata) = 0; virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) = 0; diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp index 3af8b542fa..126f8141ff 100644 --- a/servers/physics/collision_object_sw.cpp +++ b/servers/physics/collision_object_sw.cpp @@ -149,7 +149,7 @@ void CollisionObjectSW::_update_shapes() { } //not quite correct, should compute the next matrix.. - Rect3 shape_aabb = s.shape->get_aabb(); + AABB shape_aabb = s.shape->get_aabb(); Transform xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); s.aabb_cache = shape_aabb; @@ -176,10 +176,10 @@ void CollisionObjectSW::_update_shapes_with_motion(const Vector3 &p_motion) { } //not quite correct, should compute the next matrix.. - Rect3 shape_aabb = s.shape->get_aabb(); + AABB shape_aabb = s.shape->get_aabb(); Transform xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); - shape_aabb = shape_aabb.merge(Rect3(shape_aabb.position + p_motion, shape_aabb.size)); //use motion + shape_aabb = shape_aabb.merge(AABB(shape_aabb.position + p_motion, shape_aabb.size)); //use motion s.aabb_cache = shape_aabb; space->get_broadphase()->move(s.bpid, shape_aabb); diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index 67a8a44944..254947060b 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -61,7 +61,7 @@ private: Transform xform; Transform xform_inv; BroadPhaseSW::ID bpid; - Rect3 aabb_cache; //for rayqueries + AABB aabb_cache; //for rayqueries real_t area_cache; ShapeSW *shape; bool disabled; @@ -123,7 +123,7 @@ public: _FORCE_INLINE_ ShapeSW *get_shape(int p_index) const { return shapes[p_index].shape; } _FORCE_INLINE_ const Transform &get_shape_transform(int p_index) const { return shapes[p_index].xform; } _FORCE_INLINE_ const Transform &get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; } - _FORCE_INLINE_ const Rect3 &get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; } + _FORCE_INLINE_ const AABB &get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; } _FORCE_INLINE_ const real_t get_shape_area(int p_index) const { return shapes[p_index].area_cache; } _FORCE_INLINE_ Transform get_transform() const { return transform; } diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp index 7bef208237..a9431dc6d8 100644 --- a/servers/physics/collision_solver_sw.cpp +++ b/servers/physics/collision_solver_sw.cpp @@ -152,7 +152,7 @@ bool CollisionSolverSW::solve_concave(const ShapeSW *p_shape_A, const Transform //quickly compute a local AABB - Rect3 local_aabb; + AABB local_aabb; for (int i = 0; i < 3; i++) { Vector3 axis(p_transform_B.basis.get_axis(i)); @@ -291,7 +291,7 @@ bool CollisionSolverSW::solve_distance_plane(const ShapeSW *p_shape_A, const Tra return collided; } -bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const Rect3 &p_concave_hint, Vector3 *r_sep_axis) { +bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) { if (p_shape_A->is_concave()) return false; @@ -328,14 +328,14 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform //quickly compute a local AABB - bool use_cc_hint = p_concave_hint != Rect3(); - Rect3 cc_hint_aabb; + bool use_cc_hint = p_concave_hint != AABB(); + AABB cc_hint_aabb; if (use_cc_hint) { cc_hint_aabb = p_concave_hint; cc_hint_aabb.position -= p_transform_B.origin; } - Rect3 local_aabb; + AABB local_aabb; for (int i = 0; i < 3; i++) { Vector3 axis(p_transform_B.basis.get_axis(i)); diff --git a/servers/physics/collision_solver_sw.h b/servers/physics/collision_solver_sw.h index 1e38b1b54e..a40b665ff0 100644 --- a/servers/physics/collision_solver_sw.h +++ b/servers/physics/collision_solver_sw.h @@ -46,7 +46,7 @@ private: public: static bool solve_static(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const Rect3 &p_concave_hint, Vector3 *r_sep_axis = NULL); + static bool solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = NULL); }; #endif // COLLISION_SOLVER__SW_H diff --git a/servers/physics/joints/generic_6dof_joint_sw.cpp b/servers/physics/joints/generic_6dof_joint_sw.cpp index 70cc549e2d..1e323be36c 100644 --- a/servers/physics/joints/generic_6dof_joint_sw.cpp +++ b/servers/physics/joints/generic_6dof_joint_sw.cpp @@ -219,9 +219,9 @@ Generic6DOFJointSW::Generic6DOFJointSW(BodySW *rbA, BodySW *rbB, const Transform } void Generic6DOFJointSW::calculateAngleInfo() { - Basis relative_frame = m_calculatedTransformA.basis.inverse() * m_calculatedTransformB.basis; + Basis relative_frame = m_calculatedTransformB.basis.inverse() * m_calculatedTransformA.basis; - m_calculatedAxisAngleDiff = relative_frame.get_euler(); + m_calculatedAxisAngleDiff = relative_frame.get_euler_xyz(); // in euler angle mode we do not actually constrain the angular velocity // along the axes axis[0] and axis[2] (although we do use axis[1]) : diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index a7c31cf16c..ce63d84617 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -233,14 +233,7 @@ void PhysicsServerSW::area_set_space(RID p_area, RID p_space) { if (area->get_space() == space) return; //pointless - for (Set<ConstraintSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) { - RID self = E->get()->get_self(); - if (!self.is_valid()) - continue; - free(self); - } area->clear_constraints(); - area->set_space(space); }; @@ -494,14 +487,7 @@ void PhysicsServerSW::body_set_space(RID p_body, RID p_space) { if (body->get_space() == space) return; //pointless - for (Map<ConstraintSW *, int>::Element *E = body->get_constraint_map().front(); E; E = E->next()) { - RID self = E->key()->get_self(); - if (!self.is_valid()) - continue; - free(self); - } body->clear_constraint_map(); - body->set_space(space); }; @@ -709,6 +695,19 @@ real_t PhysicsServerSW::body_get_param(RID p_body, BodyParameter p_param) const return body->get_param(p_param); }; +void PhysicsServerSW::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) { + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + body->set_kinematic_margin(p_margin); +} + +real_t PhysicsServerSW::body_get_kinematic_safe_margin(RID p_body) const { + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_kinematic_margin(); +} + void PhysicsServerSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { BodySW *body = body_owner.get(p_body); @@ -902,7 +901,7 @@ bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const { return body->is_ray_pickable(); } -bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin, MotionResult *r_result) { +bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result) { BodySW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body, false); @@ -911,7 +910,7 @@ bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, cons _update_shapes(); - return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result); + return body->get_space()->test_body_motion(body, p_from, p_motion, body->get_kinematic_margin(), r_result); } PhysicsDirectBodyState *PhysicsServerSW::body_get_direct_state(RID p_body) { diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index f9eb8fa454..fa754a1c8f 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -187,6 +187,9 @@ public: virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value); virtual real_t body_get_param(RID p_body, BodyParameter p_param) const; + virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin); + virtual real_t body_get_kinematic_safe_margin(RID p_body) const; + virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant); virtual Variant body_get_state(RID p_body, BodyState p_state) const; @@ -221,7 +224,7 @@ public: virtual void body_set_ray_pickable(RID p_body, bool p_enable); virtual bool body_is_ray_pickable(RID p_body) const; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL); + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL); // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body); diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp index 6dafaac115..b204ff7a33 100644 --- a/servers/physics/shape_sw.cpp +++ b/servers/physics/shape_sw.cpp @@ -37,7 +37,7 @@ #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002 #define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.9998 -void ShapeSW::configure(const Rect3 &p_aabb) { +void ShapeSW::configure(const AABB &p_aabb) { aabb = p_aabb; configured = true; for (Map<ShapeOwnerSW *, int>::Element *E = owners.front(); E; E = E->next()) { @@ -141,7 +141,7 @@ Vector3 PlaneShapeSW::get_moment_of_inertia(real_t p_mass) const { void PlaneShapeSW::_setup(const Plane &p_plane) { plane = p_plane; - configure(Rect3(Vector3(-1e4, -1e4, -1e4), Vector3(1e4 * 2, 1e4 * 2, 1e4 * 2))); + configure(AABB(Vector3(-1e4, -1e4, -1e4), Vector3(1e4 * 2, 1e4 * 2, 1e4 * 2))); } void PlaneShapeSW::set_data(const Variant &p_data) { @@ -223,7 +223,7 @@ Vector3 RayShapeSW::get_moment_of_inertia(real_t p_mass) const { void RayShapeSW::_setup(real_t p_length) { length = p_length; - configure(Rect3(Vector3(0, 0, 0), Vector3(0.1, 0.1, length))); + configure(AABB(Vector3(0, 0, 0), Vector3(0.1, 0.1, length))); } void RayShapeSW::set_data(const Variant &p_data) { @@ -299,7 +299,7 @@ Vector3 SphereShapeSW::get_moment_of_inertia(real_t p_mass) const { void SphereShapeSW::_setup(real_t p_radius) { radius = p_radius; - configure(Rect3(Vector3(-radius, -radius, -radius), Vector3(radius * 2.0, radius * 2.0, radius * 2.0))); + configure(AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2.0, radius * 2.0, radius * 2.0))); } void SphereShapeSW::set_data(const Variant &p_data) { @@ -430,7 +430,7 @@ void BoxShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_sup bool BoxShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - Rect3 aabb(-half_extents, half_extents * 2.0); + AABB aabb(-half_extents, half_extents * 2.0); return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal); } @@ -504,7 +504,7 @@ void BoxShapeSW::_setup(const Vector3 &p_half_extents) { half_extents = p_half_extents.abs(); - configure(Rect3(-half_extents, half_extents * 2)); + configure(AABB(-half_extents, half_extents * 2)); } void BoxShapeSW::set_data(const Variant &p_data) { @@ -684,7 +684,7 @@ void CapsuleShapeSW::_setup(real_t p_height, real_t p_radius) { height = p_height; radius = p_radius; - configure(Rect3(Vector3(-radius, -radius, -height * 0.5 - radius), Vector3(radius * 2, radius * 2, height + radius * 2.0))); + configure(AABB(Vector3(-radius, -radius, -height * 0.5 - radius), Vector3(radius * 2, radius * 2, height + radius * 2.0))); } void CapsuleShapeSW::set_data(const Variant &p_data) { @@ -957,7 +957,7 @@ void ConvexPolygonShapeSW::_setup(const Vector<Vector3> &p_vertices) { if (err != OK) ERR_PRINT("Failed to build QuickHull"); - Rect3 _aabb; + AABB _aabb; for (int i = 0; i < mesh.vertices.size(); i++) { @@ -1102,7 +1102,7 @@ Vector3 FaceShapeSW::get_moment_of_inertia(real_t p_mass) const { FaceShapeSW::FaceShapeSW() { - configure(Rect3()); + configure(AABB()); } PoolVector<Vector3> ConcavePolygonShapeSW::get_faces() const { @@ -1300,13 +1300,13 @@ void ConcavePolygonShapeSW::_cull(int p_idx, _CullParams *p_params) const { } } -void ConcavePolygonShapeSW::cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const { +void ConcavePolygonShapeSW::cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const { // make matrix local to concave if (faces.size() == 0) return; - Rect3 local_aabb = p_local_aabb; + AABB local_aabb = p_local_aabb; // unlock data PoolVector<Face>::Read fr = faces.read(); @@ -1341,7 +1341,7 @@ Vector3 ConcavePolygonShapeSW::get_moment_of_inertia(real_t p_mass) const { struct _VolumeSW_BVH_Element { - Rect3 aabb; + AABB aabb; Vector3 center; int face_index; }; @@ -1372,7 +1372,7 @@ struct _VolumeSW_BVH_CompareZ { struct _VolumeSW_BVH { - Rect3 aabb; + AABB aabb; _VolumeSW_BVH *left; _VolumeSW_BVH *right; @@ -1396,7 +1396,7 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz bvh->face_index = -1; } - Rect3 aabb; + AABB aabb; for (int i = 0; i < p_size; i++) { if (i == 0) @@ -1467,7 +1467,7 @@ void ConcavePolygonShapeSW::_setup(PoolVector<Vector3> p_faces) { int src_face_count = p_faces.size(); if (src_face_count == 0) { - configure(Rect3()); + configure(AABB()); return; } ERR_FAIL_COND(src_face_count % 3); @@ -1491,7 +1491,7 @@ void ConcavePolygonShapeSW::_setup(PoolVector<Vector3> p_faces) { PoolVector<Vector3>::Write vw = vertices.write(); Vector3 *verticesw = vw.ptr(); - Rect3 _aabb; + AABB _aabb; for (int i = 0; i < src_face_count; i++) { @@ -1588,7 +1588,7 @@ Vector3 HeightMapShapeSW::get_closest_point_to(const Vector3 &p_point) const { return Vector3(); } -void HeightMapShapeSW::cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const { +void HeightMapShapeSW::cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const { } Vector3 HeightMapShapeSW::get_moment_of_inertia(real_t p_mass) const { @@ -1611,7 +1611,7 @@ void HeightMapShapeSW::_setup(PoolVector<real_t> p_heights, int p_width, int p_d PoolVector<real_t>::Read r = heights.read(); - Rect3 aabb; + AABB aabb; for (int i = 0; i < depth; i++) { diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h index 151b84c054..48832affc9 100644 --- a/servers/physics/shape_sw.h +++ b/servers/physics/shape_sw.h @@ -58,14 +58,14 @@ public: class ShapeSW : public RID_Data { RID self; - Rect3 aabb; + AABB aabb; bool configured; real_t custom_bias; Map<ShapeOwnerSW *, int> owners; protected: - void configure(const Rect3 &p_aabb); + void configure(const AABB &p_aabb); public: enum { @@ -79,7 +79,7 @@ public: virtual PhysicsServer::ShapeType get_type() const = 0; - _FORCE_INLINE_ Rect3 get_aabb() const { return aabb; } + _FORCE_INLINE_ AABB get_aabb() const { return aabb; } _FORCE_INLINE_ bool is_configured() const { return configured; } virtual bool is_concave() const { return false; } @@ -114,7 +114,7 @@ public: typedef void (*Callback)(void *p_userdata, ShapeSW *p_convex); virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } - virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const = 0; + virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const = 0; ConcaveShapeSW() {} }; @@ -299,7 +299,7 @@ struct ConcavePolygonShapeSW : public ConcaveShapeSW { struct BVH { - Rect3 aabb; + AABB aabb; int left; int right; @@ -310,7 +310,7 @@ struct ConcavePolygonShapeSW : public ConcaveShapeSW { struct _CullParams { - Rect3 aabb; + AABB aabb; Callback callback; void *userdata; const Face *faces; @@ -353,7 +353,7 @@ public: virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; - virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const; + virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const; virtual Vector3 get_moment_of_inertia(real_t p_mass) const; @@ -389,7 +389,7 @@ public: virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; - virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const; + virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const; virtual Vector3 get_moment_of_inertia(real_t p_mass) const; @@ -462,7 +462,7 @@ struct MotionShapeSW : public ShapeSW { virtual void set_data(const Variant &p_data) {} virtual Variant get_data() const { return Variant(); } - MotionShapeSW() { configure(Rect3()); } + MotionShapeSW() { configure(AABB()); } }; struct _ShapeTestConvexBSPSW { diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 7e68d54bfa..a6426b7ee0 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -176,7 +176,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); - Rect3 aabb = p_xform.xform(shape->get_aabb()); + AABB aabb = p_xform.xform(shape->get_aabb()); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); @@ -224,8 +224,8 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, false); - Rect3 aabb = p_xform.xform(shape->get_aabb()); - aabb = aabb.merge(Rect3(aabb.position + p_motion, aabb.size)); //motion + AABB aabb = p_xform.xform(shape->get_aabb()); + aabb = aabb.merge(AABB(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); /* @@ -341,7 +341,7 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); - Rect3 aabb = p_shape_xform.xform(shape->get_aabb()); + AABB aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); @@ -417,7 +417,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_ ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); - Rect3 aabb = p_shape_xform.xform(shape->get_aabb()); + AABB aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); @@ -514,7 +514,7 @@ PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() { //////////////////////////////////////////////////////////////////////////////////////////////////////////// -int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb) { +int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const AABB &p_aabb) { int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results); @@ -561,7 +561,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve r_result->collider_id = 0; r_result->collider_shape = 0; } - Rect3 body_aabb; + AABB body_aabb; for (int i = 0; i < p_body->get_shape_count(); i++) { @@ -648,7 +648,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve { // STEP 2 ATTEMPT MOTION - Rect3 motion_aabb = body_aabb; + AABB motion_aabb = body_aabb; motion_aabb.position += p_motion; motion_aabb = motion_aabb.merge(body_aabb); @@ -956,15 +956,15 @@ void SpaceSW::call_queries() { while (state_query_list.first()) { BodySW *b = state_query_list.first()->self(); - b->call_queries(); state_query_list.remove(state_query_list.first()); + b->call_queries(); } while (monitor_query_list.first()) { AreaSW *a = monitor_query_list.first()->self(); - a->call_queries(); monitor_query_list.remove(monitor_query_list.first()); + a->call_queries(); } } diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h index 270e4ef1bd..fd7e6d16a9 100644 --- a/servers/physics/space_sw.h +++ b/servers/physics/space_sw.h @@ -122,7 +122,7 @@ private: friend class PhysicsDirectSpaceStateSW; - int _cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb); + int _cull_aabb_for_body(BodySW *p_body, const AABB &p_aabb); public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index df3bf72a31..475a3fe3b3 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -35,7 +35,7 @@ #include "project_settings.h" #include "script_language.h" -RID Physics2DServerSW::shape_create(ShapeType p_shape) { +RID Physics2DServerSW::_shape_create(ShapeType p_shape) { Shape2DSW *shape = NULL; switch (p_shape) { @@ -83,7 +83,42 @@ RID Physics2DServerSW::shape_create(ShapeType p_shape) { shape->set_self(id); return id; -}; +} + +RID Physics2DServerSW::line_shape_create() { + + return _shape_create(SHAPE_LINE); +} + +RID Physics2DServerSW::ray_shape_create() { + + return _shape_create(SHAPE_RAY); +} +RID Physics2DServerSW::segment_shape_create() { + + return _shape_create(SHAPE_SEGMENT); +} +RID Physics2DServerSW::circle_shape_create() { + + return _shape_create(SHAPE_CIRCLE); +} +RID Physics2DServerSW::rectangle_shape_create() { + + return _shape_create(SHAPE_RECTANGLE); +} +RID Physics2DServerSW::capsule_shape_create() { + + return _shape_create(SHAPE_CAPSULE); +} + +RID Physics2DServerSW::convex_polygon_shape_create() { + + return _shape_create(SHAPE_CONVEX_POLYGON); +} +RID Physics2DServerSW::concave_polygon_shape_create() { + + return _shape_create(SHAPE_CONCAVE_POLYGON); +} void Physics2DServerSW::shape_set_data(RID p_shape, const Variant &p_data) { @@ -299,14 +334,7 @@ void Physics2DServerSW::area_set_space(RID p_area, RID p_space) { if (area->get_space() == space) return; //pointless - for (Set<Constraint2DSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) { - RID self = E->get()->get_self(); - if (!self.is_valid()) - continue; - free(self); - } area->clear_constraints(); - area->set_space(space); }; @@ -526,17 +554,13 @@ void Physics2DServerSW::area_set_area_monitor_callback(RID p_area, Object *p_rec /* BODY API */ -RID Physics2DServerSW::body_create(BodyMode p_mode, bool p_init_sleeping) { +RID Physics2DServerSW::body_create() { Body2DSW *body = memnew(Body2DSW); - if (p_mode != BODY_MODE_RIGID) - body->set_mode(p_mode); - if (p_init_sleeping) - body->set_state(BODY_STATE_SLEEPING, p_init_sleeping); RID rid = body_owner.make_rid(body); body->set_self(rid); return rid; -}; +} void Physics2DServerSW::body_set_space(RID p_body, RID p_space) { @@ -551,14 +575,7 @@ void Physics2DServerSW::body_set_space(RID p_body, RID p_space) { if (body->get_space() == space) return; //pointless - for (Map<Constraint2DSW *, int>::Element *E = body->get_constraint_map().front(); E; E = E->next()) { - RID self = E->key()->get_self(); - if (!self.is_valid()) - continue; - free(self); - } body->clear_constraint_map(); - body->set_space(space); }; diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index c40cf0e3e0..171a0b7a81 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -67,6 +67,9 @@ class Physics2DServerSW : public Physics2DServer { static Physics2DServerSW *singletonsw; //void _clear_query(Query2DSW *p_query); + + RID _shape_create(ShapeType p_shape); + public: struct CollCbkData { @@ -78,9 +81,17 @@ public: Vector2 *ptr; }; + virtual RID line_shape_create(); + virtual RID ray_shape_create(); + virtual RID segment_shape_create(); + virtual RID circle_shape_create(); + virtual RID rectangle_shape_create(); + virtual RID capsule_shape_create(); + virtual RID convex_polygon_shape_create(); + virtual RID concave_polygon_shape_create(); + static void _shape_col_cbk(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata); - virtual RID shape_create(ShapeType p_shape); virtual void shape_set_data(RID p_shape, const Variant &p_data); virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias); @@ -149,7 +160,7 @@ public: /* BODY API */ // create a body of a given type - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false); + virtual RID body_create(); virtual void body_set_space(RID p_body, RID p_space); virtual RID body_get_space(RID p_body) const; diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp index f8f3b620d4..f92ed18de2 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp +++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp @@ -130,19 +130,23 @@ void Physics2DServerWrapMT::finish() { Thread::wait_to_finish(thread); memdelete(thread); - /* - shape_free_cached_ids(); - area_free_cached_ids(); - body_free_cached_ids(); - pin_joint_free_cached_ids(); - groove_joint_free_cached_ids(); - damped_string_free_cached_ids(); -*/ thread = NULL; } else { physics_2d_server->finish(); } + line_shape_free_cached_ids(); + ray_shape_free_cached_ids(); + segment_shape_free_cached_ids(); + circle_shape_free_cached_ids(); + rectangle_shape_free_cached_ids(); + convex_polygon_shape_free_cached_ids(); + concave_polygon_shape_free_cached_ids(); + + space_free_cached_ids(); + area_free_cached_ids(); + body_free_cached_ids(); + if (step_sem) memdelete(step_sem); } @@ -158,12 +162,7 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool step_thread_up = false; alloc_mutex = Mutex::create(); - shape_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); - area_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); - body_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); - pin_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); - groove_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); - damped_spring_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); + pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); if (!p_create_thread) { server_thread = Thread::get_caller_id(); diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 50e9ab1005..cbc316cb7a 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -64,21 +64,10 @@ class Physics2DServerWrapMT : public Physics2DServer { void thread_exit(); - Mutex *alloc_mutex; bool first_frame; - int shape_pool_max_size; - List<RID> shape_id_pool; - int area_pool_max_size; - List<RID> area_id_pool; - int body_pool_max_size; - List<RID> body_id_pool; - int pin_joint_pool_max_size; - List<RID> pin_joint_id_pool; - int groove_joint_pool_max_size; - List<RID> groove_joint_id_pool; - int damped_spring_joint_pool_max_size; - List<RID> damped_spring_joint_id_pool; + Mutex *alloc_mutex; + int pool_max_size; public: #define ServerName Physics2DServer @@ -87,7 +76,15 @@ public: #include "servers/server_wrap_mt_common.h" //FUNC1RID(shape,ShapeType); todo fix - FUNC1R(RID, shape_create, ShapeType); + FUNCRID(line_shape) + FUNCRID(ray_shape) + FUNCRID(segment_shape) + FUNCRID(circle_shape) + FUNCRID(rectangle_shape) + FUNCRID(capsule_shape) + FUNCRID(convex_polygon_shape) + FUNCRID(concave_polygon_shape) + FUNC2(shape_set_data, RID, const Variant &); FUNC2(shape_set_custom_solver_bias, RID, real_t); @@ -104,7 +101,7 @@ public: /* SPACE API */ - FUNC0R(RID, space_create); + FUNCRID(space); FUNC2(space_set_active, RID, bool); FUNC1RC(bool, space_is_active, RID); @@ -134,7 +131,7 @@ public: /* AREA API */ //FUNC0RID(area); - FUNC0R(RID, area_create); + FUNCRID(area); FUNC2(area_set_space, RID, RID); FUNC1RC(RID, area_get_space, RID); @@ -174,7 +171,7 @@ public: /* BODY API */ //FUNC2RID(body,BodyMode,bool); - FUNC2R(RID, body_create, BodyMode, bool) + FUNCRID(body) FUNC2(body_set_space, RID, RID); FUNC1RC(RID, body_get_space, RID); @@ -269,6 +266,8 @@ public: ///FUNC5RID(groove_joint,const Vector2&,const Vector2&,const Vector2&,RID,RID); ///FUNC4RID(damped_spring_joint,const Vector2&,const Vector2&,RID,RID); + //TODO need to convert this to FUNCRID, but it's a hassle.. + FUNC3R(RID, pin_joint_create, const Vector2 &, RID, RID); FUNC5R(RID, groove_joint_create, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID); FUNC4R(RID, damped_spring_joint_create, const Vector2 &, const Vector2 &, RID, RID); diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 6eaaaa777b..3b8eb19dd1 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -626,13 +626,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co int amount = _cull_aabb_for_body(p_body, motion_aabb); - for (int j = 0; j < p_body->get_shape_count(); j++) { + for (int body_shape_idx = 0; body_shape_idx < p_body->get_shape_count(); body_shape_idx++) { - if (p_body->is_shape_set_as_disabled(j)) + if (p_body->is_shape_set_as_disabled(body_shape_idx)) continue; - Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j); - Shape2DSW *body_shape = p_body->get_shape(j); + Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(body_shape_idx); + Shape2DSW *body_shape = p_body->get_shape(body_shape_idx); bool stuck = false; @@ -642,14 +642,14 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co for (int i = 0; i < amount; i++) { const CollisionObject2DSW *col_obj = intersection_query_results[i]; - int shape_idx = intersection_query_subindex_results[i]; - Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + int col_shape_idx = intersection_query_subindex_results[i]; + Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx); bool excluded = false; for (int k = 0; k < excluded_shape_pair_count; k++) { - if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == shape_idx) { + if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == col_shape_idx) { excluded = true; break; } @@ -660,7 +660,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co continue; } - Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); + Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(col_shape_idx); //test initial overlap, does it collide if going all the way? if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { continue; @@ -669,7 +669,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co //test initial overlap if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { - if (col_obj->is_shape_set_as_one_way_collision(j)) { + if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { continue; } @@ -698,7 +698,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } } - if (col_obj->is_shape_set_as_one_way_collision(j)) { + if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { Vector2 cd[2]; Physics2DServerSW::CollCbkData cbk; @@ -710,7 +710,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.valid_depth = 10e20; Vector2 sep = mnormal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0); + bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0); if (!collided || cbk.amount == 0) { continue; } @@ -726,7 +726,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co safe = 0; unsafe = 0; - best_shape = j; //sadly it's the best + best_shape = body_shape_idx; //sadly it's the best break; } if (best_safe == 1.0) { @@ -736,7 +736,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co safe = best_safe; unsafe = best_unsafe; - best_shape = j; + best_shape = body_shape_idx; } } } @@ -969,15 +969,15 @@ void Space2DSW::call_queries() { while (state_query_list.first()) { Body2DSW *b = state_query_list.first()->self(); - b->call_queries(); state_query_list.remove(state_query_list.first()); + b->call_queries(); } while (monitor_query_list.first()) { Area2DSW *a = monitor_query_list.first()->self(); - a->call_queries(); monitor_query_list.remove(monitor_query_list.first()); + a->call_queries(); } } diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index b2e1d541ab..650d3d0f62 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -28,7 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "physics_2d_server.h" +#include "core/project_settings.h" #include "print_string.h" + Physics2DServer *Physics2DServer::singleton = NULL; void Physics2DDirectBodyState::integrate_forces() { @@ -473,7 +475,15 @@ bool Physics2DServer::_body_test_motion(RID p_body, const Transform2D &p_from, c void Physics2DServer::_bind_methods() { - ClassDB::bind_method(D_METHOD("shape_create", "type"), &Physics2DServer::shape_create); + ClassDB::bind_method(D_METHOD("line_shape_create"), &Physics2DServer::line_shape_create); + ClassDB::bind_method(D_METHOD("ray_shape_create"), &Physics2DServer::ray_shape_create); + ClassDB::bind_method(D_METHOD("segment_shape_create"), &Physics2DServer::segment_shape_create); + ClassDB::bind_method(D_METHOD("circle_shape_create"), &Physics2DServer::circle_shape_create); + ClassDB::bind_method(D_METHOD("rectangle_shape_create"), &Physics2DServer::rectangle_shape_create); + ClassDB::bind_method(D_METHOD("capsule_shape_create"), &Physics2DServer::capsule_shape_create); + ClassDB::bind_method(D_METHOD("convex_polygon_shape_create"), &Physics2DServer::convex_polygon_shape_create); + ClassDB::bind_method(D_METHOD("concave_polygon_shape_create"), &Physics2DServer::concave_polygon_shape_create); + ClassDB::bind_method(D_METHOD("shape_set_data", "shape", "data"), &Physics2DServer::shape_set_data); ClassDB::bind_method(D_METHOD("shape_get_type", "shape"), &Physics2DServer::shape_get_type); @@ -519,7 +529,7 @@ void Physics2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_monitor_callback); - ClassDB::bind_method(D_METHOD("body_create", "mode", "init_sleeping"), &Physics2DServer::body_create, DEFVAL(BODY_MODE_RIGID), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("body_create"), &Physics2DServer::body_create); ClassDB::bind_method(D_METHOD("body_set_space", "body", "space"), &Physics2DServer::body_set_space); ClassDB::bind_method(D_METHOD("body_get_space", "body"), &Physics2DServer::body_get_space); @@ -692,3 +702,68 @@ Physics2DServer::~Physics2DServer() { singleton = NULL; } + +Vector<Physics2DServerManager::ClassInfo> Physics2DServerManager::physics_2d_servers; +int Physics2DServerManager::default_server_id = -1; +int Physics2DServerManager::default_server_priority = -1; +const String Physics2DServerManager::setting_property_name("physics/2d/physics_engine"); + +void Physics2DServerManager::on_servers_changed() { + + String physics_servers("DEFAULT"); + for (int i = get_servers_count() - 1; 0 <= i; --i) { + physics_servers += "," + get_server_name(i); + } + ProjectSettings::get_singleton()->set_custom_property_info(setting_property_name, PropertyInfo(Variant::STRING, setting_property_name, PROPERTY_HINT_ENUM, physics_servers)); +} + +void Physics2DServerManager::register_server(const String &p_name, CreatePhysics2DServerCallback p_creat_callback) { + + ERR_FAIL_COND(!p_creat_callback); + ERR_FAIL_COND(find_server_id(p_name) != -1); + physics_2d_servers.push_back(ClassInfo(p_name, p_creat_callback)); + on_servers_changed(); +} + +void Physics2DServerManager::set_default_server(const String &p_name, int p_priority) { + + const int id = find_server_id(p_name); + ERR_FAIL_COND(id == -1); // Not found + if (default_server_priority < p_priority) { + default_server_id = id; + default_server_priority = p_priority; + } +} + +int Physics2DServerManager::find_server_id(const String &p_name) { + + for (int i = physics_2d_servers.size() - 1; 0 <= i; --i) { + if (p_name == physics_2d_servers[i].name) { + return i; + } + } + return -1; +} + +int Physics2DServerManager::get_servers_count() { + return physics_2d_servers.size(); +} + +String Physics2DServerManager::get_server_name(int p_id) { + ERR_FAIL_INDEX_V(p_id, get_servers_count(), ""); + return physics_2d_servers[p_id].name; +} + +Physics2DServer *Physics2DServerManager::new_default_server() { + ERR_FAIL_COND_V(default_server_id == -1, NULL); + return physics_2d_servers[default_server_id].create_callback(); +} + +Physics2DServer *Physics2DServerManager::new_server(const String &p_name) { + int id = find_server_id(p_name); + if (id == -1) { + return NULL; + } else { + return physics_2d_servers[id].create_callback(); + } +} diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 18f4f460b6..241255bdb5 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -252,7 +252,15 @@ public: SHAPE_CUSTOM, ///< Server-Implementation based custom shape, calling shape_create() with this value will result in an error }; - virtual RID shape_create(ShapeType p_shape) = 0; + virtual RID line_shape_create() = 0; + virtual RID ray_shape_create() = 0; + virtual RID segment_shape_create() = 0; + virtual RID circle_shape_create() = 0; + virtual RID rectangle_shape_create() = 0; + virtual RID capsule_shape_create() = 0; + virtual RID convex_polygon_shape_create() = 0; + virtual RID concave_polygon_shape_create() = 0; + virtual void shape_set_data(RID p_shape, const Variant &p_data) = 0; virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) = 0; @@ -366,7 +374,7 @@ public: //BODY_MODE_SOFT ?? }; - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) = 0; + virtual RID body_create() = 0; virtual void body_set_space(RID p_body, RID p_space) = 0; virtual RID body_get_space(RID p_body) const = 0; @@ -590,6 +598,43 @@ public: Physics2DTestMotionResult(); }; +typedef Physics2DServer *(*CreatePhysics2DServerCallback)(); + +class Physics2DServerManager { + struct ClassInfo { + String name; + CreatePhysics2DServerCallback create_callback; + + ClassInfo() + : name(""), create_callback(NULL) {} + + ClassInfo(String p_name, CreatePhysics2DServerCallback p_create_callback) + : name(p_name), create_callback(p_create_callback) {} + + ClassInfo(const ClassInfo &p_ci) + : name(p_ci.name), create_callback(p_ci.create_callback) {} + }; + + static Vector<ClassInfo> physics_2d_servers; + static int default_server_id; + static int default_server_priority; + +public: + static const String setting_property_name; + +private: + static void on_servers_changed(); + +public: + static void register_server(const String &p_name, CreatePhysics2DServerCallback p_creat_callback); + static void set_default_server(const String &p_name, int p_priority = 0); + static int find_server_id(const String &p_name); + static int get_servers_count(); + static String get_server_name(int p_id); + static Physics2DServer *new_default_server(); + static Physics2DServer *new_server(const String &p_name); +}; + VARIANT_ENUM_CAST(Physics2DServer::ShapeType); VARIANT_ENUM_CAST(Physics2DServer::SpaceParameter); VARIANT_ENUM_CAST(Physics2DServer::AreaParameter); diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 360808ce8c..88cd728a94 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -28,7 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "physics_server.h" +#include "core/project_settings.h" #include "print_string.h" + PhysicsServer *PhysicsServer::singleton = NULL; void PhysicsDirectBodyState::integrate_forces() { @@ -479,6 +481,9 @@ void PhysicsServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_param", "body", "param", "value"), &PhysicsServer::body_set_param); ClassDB::bind_method(D_METHOD("body_get_param", "body", "param"), &PhysicsServer::body_get_param); + ClassDB::bind_method(D_METHOD("body_set_kinematic_safe_margin", "body", "margin"), &PhysicsServer::body_set_kinematic_safe_margin); + ClassDB::bind_method(D_METHOD("body_get_kinematic_safe_margin", "body"), &PhysicsServer::body_get_kinematic_safe_margin); + ClassDB::bind_method(D_METHOD("body_set_state", "body", "state", "value"), &PhysicsServer::body_set_state); ClassDB::bind_method(D_METHOD("body_get_state", "body", "state"), &PhysicsServer::body_get_state); @@ -673,6 +678,7 @@ void PhysicsServer::_bind_methods() { BIND_ENUM_CONSTANT(BODY_MODE_STATIC); BIND_ENUM_CONSTANT(BODY_MODE_KINEMATIC); BIND_ENUM_CONSTANT(BODY_MODE_RIGID); + BIND_ENUM_CONSTANT(BODY_MODE_SOFT); BIND_ENUM_CONSTANT(BODY_MODE_CHARACTER); BIND_ENUM_CONSTANT(BODY_PARAM_BOUNCE); @@ -732,3 +738,68 @@ PhysicsServer::~PhysicsServer() { singleton = NULL; } + +Vector<PhysicsServerManager::ClassInfo> PhysicsServerManager::physics_servers; +int PhysicsServerManager::default_server_id = -1; +int PhysicsServerManager::default_server_priority = -1; +const String PhysicsServerManager::setting_property_name("physics/3d/physics_engine"); + +void PhysicsServerManager::on_servers_changed() { + + String physics_servers("DEFAULT"); + for (int i = get_servers_count() - 1; 0 <= i; --i) { + physics_servers += "," + get_server_name(i); + } + ProjectSettings::get_singleton()->set_custom_property_info(setting_property_name, PropertyInfo(Variant::STRING, setting_property_name, PROPERTY_HINT_ENUM, physics_servers)); +} + +void PhysicsServerManager::register_server(const String &p_name, CreatePhysicsServerCallback p_creat_callback) { + + ERR_FAIL_COND(!p_creat_callback); + ERR_FAIL_COND(find_server_id(p_name) != -1); + physics_servers.push_back(ClassInfo(p_name, p_creat_callback)); + on_servers_changed(); +} + +void PhysicsServerManager::set_default_server(const String &p_name, int p_priority) { + + const int id = find_server_id(p_name); + ERR_FAIL_COND(id == -1); // Not found + if (default_server_priority < p_priority) { + default_server_id = id; + default_server_priority = p_priority; + } +} + +int PhysicsServerManager::find_server_id(const String &p_name) { + + for (int i = physics_servers.size() - 1; 0 <= i; --i) { + if (p_name == physics_servers[i].name) { + return i; + } + } + return -1; +} + +int PhysicsServerManager::get_servers_count() { + return physics_servers.size(); +} + +String PhysicsServerManager::get_server_name(int p_id) { + ERR_FAIL_INDEX_V(p_id, get_servers_count(), ""); + return physics_servers[p_id].name; +} + +PhysicsServer *PhysicsServerManager::new_default_server() { + ERR_FAIL_COND_V(default_server_id == -1, NULL); + return physics_servers[default_server_id].create_callback(); +} + +PhysicsServer *PhysicsServerManager::new_server(const String &p_name) { + int id = find_server_id(p_name); + if (id == -1) { + return NULL; + } else { + return physics_servers[id].create_callback(); + } +} diff --git a/servers/physics_server.h b/servers/physics_server.h index 8cec125646..64c67eae2a 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -357,7 +357,7 @@ public: BODY_MODE_STATIC, BODY_MODE_KINEMATIC, BODY_MODE_RIGID, - //BODY_MODE_SOFT + BODY_MODE_SOFT, BODY_MODE_CHARACTER }; @@ -411,6 +411,9 @@ public: virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0; virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0; + virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) = 0; + virtual real_t body_get_kinematic_safe_margin(RID p_body) const = 0; + //state enum BodyState { BODY_STATE_TRANSFORM, @@ -482,7 +485,7 @@ public: Variant collider_metadata; }; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL) = 0; + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL) = 0; /* JOINT API */ @@ -658,6 +661,43 @@ public: ~PhysicsServer(); }; +typedef PhysicsServer *(*CreatePhysicsServerCallback)(); + +class PhysicsServerManager { + struct ClassInfo { + String name; + CreatePhysicsServerCallback create_callback; + + ClassInfo() + : name(""), create_callback(NULL) {} + + ClassInfo(String p_name, CreatePhysicsServerCallback p_create_callback) + : name(p_name), create_callback(p_create_callback) {} + + ClassInfo(const ClassInfo &p_ci) + : name(p_ci.name), create_callback(p_ci.create_callback) {} + }; + + static Vector<ClassInfo> physics_servers; + static int default_server_id; + static int default_server_priority; + +public: + static const String setting_property_name; + +private: + static void on_servers_changed(); + +public: + static void register_server(const String &p_name, CreatePhysicsServerCallback p_creat_callback); + static void set_default_server(const String &p_name, int p_priority = 0); + static int find_server_id(const String &p_name); + static int get_servers_count(); + static String get_server_name(int p_id); + static PhysicsServer *new_default_server(); + static PhysicsServer *new_server(const String &p_name); +}; + VARIANT_ENUM_CAST(PhysicsServer::ShapeType); VARIANT_ENUM_CAST(PhysicsServer::SpaceParameter); VARIANT_ENUM_CAST(PhysicsServer::AreaParameter); diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 7a9328e30f..99493afc40 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "register_server_types.h" +#include "engine.h" #include "project_settings.h" #include "arvr/arvr_interface.h" @@ -49,6 +50,9 @@ #include "audio/effects/audio_effect_reverb.h" #include "audio/effects/audio_effect_stereo_enhance.h" #include "audio_server.h" +#include "physics/physics_server_sw.h" +#include "physics_2d/physics_2d_server_sw.h" +#include "physics_2d/physics_2d_server_wrap_mt.h" #include "physics_2d_server.h" #include "physics_server.h" #include "script_debugger_remote.h" @@ -74,6 +78,14 @@ static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsag ShaderTypes *shader_types = NULL; +PhysicsServer *_createGodotPhysicsCallback() { + return memnew(PhysicsServerSW); +} + +Physics2DServer *_createGodotPhysics2DCallback() { + return Physics2DServerWrapMT::init_server<Physics2DServerSW>(); +} + void register_server_types() { ClassDB::register_virtual_class<VisualServer>(); @@ -82,12 +94,6 @@ void register_server_types() { ClassDB::register_virtual_class<Physics2DServer>(); ClassDB::register_class<ARVRServer>(); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("VisualServer", VisualServer::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("AudioServer", AudioServer::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("PhysicsServer", PhysicsServer::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Physics2DServer", Physics2DServer::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ARVRServer", ARVRServer::get_singleton())); - shader_types = memnew(ShaderTypes); ClassDB::register_virtual_class<ARVRInterface>(); @@ -144,9 +150,31 @@ void register_server_types() { ClassDB::register_virtual_class<PhysicsShapeQueryResult>(); ScriptDebuggerRemote::resource_usage_func = _debugger_get_resource_usage; + + // Physics 2D + GLOBAL_DEF(Physics2DServerManager::setting_property_name, "DEFAULT"); + ProjectSettings::get_singleton()->set_custom_property_info(Physics2DServerManager::setting_property_name, PropertyInfo(Variant::STRING, Physics2DServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT")); + + Physics2DServerManager::register_server("GodotPhysics", &_createGodotPhysics2DCallback); + Physics2DServerManager::set_default_server("GodotPhysics"); + + // Physics 3D + GLOBAL_DEF(PhysicsServerManager::setting_property_name, "DEFAULT"); + ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServerManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT")); + + PhysicsServerManager::register_server("GodotPhysics", &_createGodotPhysicsCallback); + PhysicsServerManager::set_default_server("GodotPhysics"); } void unregister_server_types() { memdelete(shader_types); } + +void register_server_singletons() { + Engine::get_singleton()->add_singleton(Engine::Singleton("VisualServer", VisualServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer", PhysicsServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Physics2DServer", Physics2DServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ARVRServer", ARVRServer::get_singleton())); +} diff --git a/servers/register_server_types.h b/servers/register_server_types.h index 2b3ac816ac..e53626ca30 100644 --- a/servers/register_server_types.h +++ b/servers/register_server_types.h @@ -33,4 +33,6 @@ void register_server_types(); void unregister_server_types(); +void register_server_singletons(); + #endif // REGISTER_SERVER_TYPES_H diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index cd4b465d79..21d059c48e 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -234,7 +234,7 @@ public: virtual RID mesh_create() = 0; - virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<Rect3> &p_bone_aabbs = Vector<Rect3>()) = 0; + virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) = 0; virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount) = 0; virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0; @@ -242,6 +242,8 @@ public: virtual void mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode) = 0; virtual VS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; + virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) = 0; + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; @@ -254,17 +256,17 @@ public: virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const = 0; virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const = 0; - virtual Rect3 mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; + virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const = 0; - virtual Vector<Rect3> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; + virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; virtual void mesh_remove_surface(RID p_mesh, int p_index) = 0; virtual int mesh_get_surface_count(RID p_mesh) const = 0; - virtual void mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb) = 0; - virtual Rect3 mesh_get_custom_aabb(RID p_mesh) const = 0; + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; + virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; - virtual Rect3 mesh_get_aabb(RID p_mesh, RID p_skeleton) const = 0; + virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton) const = 0; virtual void mesh_clear(RID p_mesh) = 0; /* MULTIMESH API */ @@ -288,7 +290,7 @@ public: virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0; virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0; - virtual Rect3 multimesh_get_aabb(RID p_multimesh) const = 0; + virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; /* IMMEDIATE API */ @@ -304,7 +306,7 @@ public: virtual void immediate_clear(RID p_immediate) = 0; virtual void immediate_set_material(RID p_immediate, RID p_material) = 0; virtual RID immediate_get_material(RID p_immediate) const = 0; - virtual Rect3 immediate_get_aabb(RID p_immediate) const = 0; + virtual AABB immediate_get_aabb(RID p_immediate) const = 0; /* SKELETON API */ @@ -320,6 +322,10 @@ public: virtual RID light_create(VS::LightType p_type) = 0; + RID directional_light_create() { return light_create(VS::LIGHT_DIRECTIONAL); } + RID omni_light_create() { return light_create(VS::LIGHT_OMNI); } + RID spot_light_create() { return light_create(VS::LIGHT_SPOT); } + virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, VS::LightParam p_param, float p_value) = 0; virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; @@ -344,7 +350,7 @@ public: virtual bool light_has_shadow(RID p_light) const = 0; virtual VS::LightType light_get_type(RID p_light) const = 0; - virtual Rect3 light_get_aabb(RID p_light) const = 0; + virtual AABB light_get_aabb(RID p_light) const = 0; virtual float light_get_param(RID p_light, VS::LightParam p_param) = 0; virtual Color light_get_color(RID p_light) = 0; virtual uint64_t light_get_version(RID p_light) const = 0; @@ -366,7 +372,7 @@ public: virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0; virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0; - virtual Rect3 reflection_probe_get_aabb(RID p_probe) const = 0; + virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0; virtual VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0; virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0; virtual Vector3 reflection_probe_get_extents(RID p_probe) const = 0; @@ -384,8 +390,8 @@ public: virtual RID gi_probe_create() = 0; - virtual void gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds) = 0; - virtual Rect3 gi_probe_get_bounds(RID p_probe) const = 0; + virtual void gi_probe_set_bounds(RID p_probe, const AABB &p_bounds) = 0; + virtual AABB gi_probe_get_bounds(RID p_probe) const = 0; virtual void gi_probe_set_cell_size(RID p_probe, float p_range) = 0; virtual float gi_probe_get_cell_size(RID p_probe) const = 0; @@ -440,7 +446,7 @@ public: virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; - virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) = 0; + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0; virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0; virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0; virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; @@ -454,8 +460,8 @@ public: virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0; virtual void particles_request_process(RID p_particles) = 0; - virtual Rect3 particles_get_current_aabb(RID p_particles) = 0; - virtual Rect3 particles_get_aabb(RID p_particles) const = 0; + virtual AABB particles_get_current_aabb(RID p_particles) = 0; + virtual AABB particles_get_aabb(RID p_particles) const = 0; virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; @@ -876,7 +882,7 @@ public: case Item::Command::TYPE_MESH: { const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); - Rect3 aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton); + AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); @@ -884,7 +890,7 @@ public: case Item::Command::TYPE_MULTIMESH: { const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c); - Rect3 aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); + AABB aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); @@ -893,7 +899,7 @@ public: const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c); if (particles_cmd->particles.is_valid()) { - Rect3 aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles); + AABB aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); } diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 09ac9959f9..a92370f1f0 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -175,7 +175,7 @@ public: void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color); void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color); void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()); - void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true); + void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = false); void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()); void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()); void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index c644fd2d55..9432d3fdd9 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -102,6 +102,7 @@ void VisualServerRaster::draw() { VSG::viewport->draw_viewports(); VSG::scene->render_probes(); + _draw_margins(); VSG::rasterizer->end_frame(); while (frame_drawn_callbacks.front()) { @@ -120,7 +121,7 @@ void VisualServerRaster::draw() { frame_drawn_callbacks.pop_front(); } - _draw_margins(); + emit_signal("frame_drawn_in_thread"); } void VisualServerRaster::sync() { } diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 302f13ee4f..08a0cfa269 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -73,527 +73,12 @@ class VisualServerRaster : public VisualServer { List<FrameDrawnCallbacks> frame_drawn_callbacks; -// FIXME: Kept as reference for future implementation -#if 0 - struct Room { - - bool occlude_exterior; - BSP_Tree bounds; - Room() { occlude_exterior=true; } - }; - - - BalloonAllocator<> octree_allocator; - - struct OctreeAllocator { - - static BalloonAllocator<> *allocator; - - _FORCE_INLINE_ static void *alloc(size_t p_size) { return allocator->alloc(p_size); } - _FORCE_INLINE_ static void free(void *p_ptr) { return allocator->free(p_ptr); } - - }; - - struct Portal { - - bool enabled; - float disable_distance; - Color disable_color; - float connect_range; - Vector<Point2> shape; - Rect2 bounds; - - - Portal() { enabled=true; disable_distance=50; disable_color=Color(); connect_range=0.8; } - }; - - struct BakedLight { - - Rasterizer::BakedLightData data; - PoolVector<int> sampler; - Rect3 octree_aabb; - Size2i octree_tex_size; - Size2i light_tex_size; - - }; - - struct BakedLightSampler { - - float params[BAKED_LIGHT_SAMPLER_MAX]; - int resolution; - Vector<Vector3> dp_cache; - - BakedLightSampler() { - params[BAKED_LIGHT_SAMPLER_STRENGTH]=1.0; - params[BAKED_LIGHT_SAMPLER_ATTENUATION]=1.0; - params[BAKED_LIGHT_SAMPLER_RADIUS]=1.0; - params[BAKED_LIGHT_SAMPLER_DETAIL_RATIO]=0.1; - resolution=16; - } - }; - - void _update_baked_light_sampler_dp_cache(BakedLightSampler * blsamp); - struct Camera { - - enum Type { - PERSPECTIVE, - ORTHOGONAL - }; - Type type; - float fov; - float znear,zfar; - float size; - uint32_t visible_layers; - bool vaspect; - RID env; - - Transform transform; - - Camera() { - - visible_layers=0xFFFFFFFF; - fov=60; - type=PERSPECTIVE; - znear=0.1; zfar=100; - size=1.0; - vaspect=false; - - } - }; - - - struct Instance; - typedef Set<Instance*,Comparator<Instance*>,OctreeAllocator> InstanceSet; - struct Scenario; - - struct Instance { - - enum { - - MAX_LIGHTS=4 - }; - - RID self; - OctreeElementID octree_id; - Scenario *scenario; - bool update; - bool update_aabb; - bool update_materials; - Instance *update_next; - InstanceType base_type; - - RID base_rid; - - Rect3 aabb; - Rect3 transformed_aabb; - uint32_t object_ID; - bool visible; - bool visible_in_all_rooms; - uint32_t layer_mask; - float draw_range_begin; - float draw_range_end; - float extra_margin; - - - - Rasterizer::InstanceData data; - - - Set<Instance*> auto_rooms; - Set<Instance*> valid_auto_rooms; - Instance *room; - List<Instance*>::Element *RE; - Instance *baked_light; - List<Instance*>::Element *BLE; - Instance *sampled_light; - bool exterior; - - uint64_t last_render_pass; - uint64_t last_frame_pass; - - uint64_t version; // changes to this, and changes to base increase version - - InstanceSet lights; - bool light_cache_dirty; - - - - struct RoomInfo { - - Transform affine_inverse; - Room *room; - List<Instance*> owned_geometry_instances; - List<Instance*> owned_portal_instances; - List<Instance*> owned_room_instances; - List<Instance*> owned_light_instances; //not used, but just for the sake of it - Set<Instance*> disconnected_child_portals; - Set<Instance*> owned_autoroom_geometry; - uint64_t last_visited_pass; - RoomInfo() { last_visited_pass=0; } - - }; - - struct PortalInfo { - - Portal *portal; - Set<Instance*> candidate_set; - Instance *connected; - uint64_t last_visited_pass; - - Plane plane_cache; - Vector<Vector3> transformed_point_cache; - - - PortalInfo() { connected=NULL; last_visited_pass=0;} - }; - - struct LightInfo { - - RID instance; - int light_set_index; - uint64_t last_version; - uint64_t last_add_pass; - List<RID>::Element *D; // directional light in scenario - InstanceSet affected; - bool enabled; - float dtc; //distance to camera, used for sorting - - - LightInfo() { - - D=NULL; - light_set_index=-1; - last_add_pass=0; - enabled=true; - } - }; - - struct BakedLightInfo { - - BakedLight *baked_light; - Transform affine_inverse; - List<Instance*> owned_instances; - }; - - struct BakedLightSamplerInfo { - - Set<Instance*> baked_lights; - Set<Instance*> owned_instances; - BakedLightSampler *sampler; - int resolution; - Vector<Color> light_bufer; - RID sampled_light; - uint64_t last_pass; - Transform xform; // viewspace normal to lightspace, might not use one. - BakedLightSamplerInfo() { - sampler=NULL; - last_pass=0; - resolution=0; - } - }; - - struct ParticlesInfo { - - RID instance; - }; - - - RoomInfo *room_info; - LightInfo *light_info; - ParticlesInfo *particles_info; - PortalInfo * portal_info; - BakedLightInfo * baked_light_info; - BakedLightSamplerInfo * baked_light_sampler_info; - - - Instance() { - octree_id=0; - update_next=0; - object_ID=0; - last_render_pass=0; - last_frame_pass=0; - light_info=0; - particles_info=0; - update_next=NULL; - update=false; - visible=true; - data.cast_shadows=SHADOW_CASTING_SETTING_ON; - data.receive_shadows=true; - data.depth_scale=false; - data.billboard=false; - data.billboard_y=false; - data.baked_light=NULL; - data.baked_light_octree_xform=NULL; - data.baked_lightmap_id=-1; - version=1; - room_info=NULL; - room=NULL; - RE=NULL; - portal_info=NULL; - exterior=false; - layer_mask=1; - draw_range_begin=0; - draw_range_end=0; - extra_margin=0; - visible_in_all_rooms=false; - update_aabb=false; - update_materials=false; - - baked_light=NULL; - baked_light_info=NULL; - baked_light_sampler_info=NULL; - sampled_light=NULL; - BLE=NULL; - - light_cache_dirty=true; - - } - - ~Instance() { - - if (light_info) - memdelete(light_info); - if (particles_info) - memdelete(particles_info); - if (room_info) - memdelete(room_info); - if (portal_info) - memdelete(portal_info); - if (baked_light_info) - memdelete(baked_light_info); - }; - }; - - struct _InstanceLightsort { - - bool operator()(const Instance* p_A, const Instance* p_B) const { return p_A->light_info->dtc < p_B->light_info->dtc; } - }; - - struct Scenario { - - - ScenarioDebugMode debug; - RID self; - // well wtf, balloon allocator is slower? - typedef ::Octree<Instance,true> Octree; - - Octree octree; - - List<RID> directional_lights; - RID environment; - RID fallback_environment; - - Instance *dirty_instances; - - Scenario() { dirty_instances=NULL; debug=SCENARIO_DEBUG_DISABLED; } - }; - - - - mutable RID_Owner<Rasterizer::ShaderMaterial> canvas_item_material_owner; - - - - struct Viewport { - - RID self; - RID parent; - - VisualServer::ViewportRect rect; - RID camera; - RID scenario; - RID viewport_data; - - RenderTargetUpdateMode render_target_update_mode; - RID render_target; - RID render_target_texture; - - Rect2 rt_to_screen_rect; - - bool hide_scenario; - bool hide_canvas; - bool transparent_bg; - bool queue_capture; - bool render_target_vflip; - bool render_target_clear_on_new_frame; - bool render_target_clear; - bool disable_environment; - - Image capture; - - bool rendered_in_prev_frame; - - struct CanvasKey { - - int layer; - RID canvas; - bool operator<(const CanvasKey& p_canvas) const { if (layer==p_canvas.layer) return canvas < p_canvas.canvas; return layer<p_canvas.layer; } - CanvasKey() { layer=0; } - CanvasKey(const RID& p_canvas, int p_layer) { canvas=p_canvas; layer=p_layer; } - }; - - struct CanvasData { - - Canvas *canvas; - Transform2D transform; - int layer; - }; - - Transform2D global_transform; - - Map<RID,CanvasData> canvas_map; - - SelfList<Viewport> update_list; - - Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true; disable_environment=false; } - }; - - SelfList<Viewport>::List viewport_update_list; - - Map<RID,int> screen_viewports; - - struct CullRange { - - Plane nearp; - float min,max; - float z_near,z_far; - - void add_aabb(const Rect3& p_aabb) { - - - } - }; - - struct Cursor { - - Point2 pos; - float rot; - RID texture; - Point2 center; - bool visible; - Rect2 region; - Cursor() { - - rot = 0; - visible = false; - region = Rect2(); - }; - }; - - Rect2 canvas_clip; - Color clear_color; - Cursor cursors[MAX_CURSORS]; - RID default_cursor_texture; - - static void* instance_pair(void *p_self, OctreeElementID,Instance *p_A,int, OctreeElementID,Instance *p_B,int); - static void instance_unpair(void *p_self, OctreeElementID,Instance *p_A,int, OctreeElementID,Instance *p_B,int,void*); - - Instance *instance_cull_result[MAX_INSTANCE_CULL]; - Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps - Instance *light_cull_result[MAX_LIGHTS_CULLED]; - int light_cull_count; - - Instance *exterior_portal_cull_result[MAX_EXTERIOR_PORTALS]; - int exterior_portal_cull_count; - bool exterior_visited; - - Instance *light_sampler_cull_result[MAX_LIGHT_SAMPLERS]; - int light_samplers_culled; - - Instance *room_cull_result[MAX_ROOM_CULL]; - int room_cull_count; - bool room_cull_enabled; - bool light_discard_enabled; - bool shadows_enabled; - int black_margin[4]; - RID black_image[4]; - - Vector<Vector3> aabb_random_points; - Vector<Vector3> transformed_aabb_random_points; - - void _instance_validate_autorooms(Instance *p_geometry); - - void _portal_disconnect(Instance *p_portal,bool p_cleanup=false); - void _portal_attempt_connect(Instance *p_portal); - void _dependency_queue_update(RID p_rid, bool p_update_aabb=false, bool p_update_materials=false); - _FORCE_INLINE_ void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false,bool p_update_materials=false); - void _update_instances(); - void _update_instance_aabb(Instance *p_instance); - void _update_instance(Instance *p_instance); - void _free_attached_instances(RID p_rid,bool p_free_scenario=false); - void _clean_up_owner(RID_OwnerBase *p_owner,String p_type); - - Instance *instance_update_list; - - //RID default_scenario; - //RID default_viewport; - - RID test_cube; - - - mutable RID_Owner<Room> room_owner; - mutable RID_Owner<Portal> portal_owner; - - mutable RID_Owner<BakedLight> baked_light_owner; - mutable RID_Owner<BakedLightSampler> baked_light_sampler_owner; - - mutable RID_Owner<Camera> camera_owner; - mutable RID_Owner<Viewport> viewport_owner; - - mutable RID_Owner<Scenario> scenario_owner; - mutable RID_Owner<Instance> instance_owner; - - mutable RID_Owner<Canvas> canvas_owner; - mutable RID_Owner<CanvasItem> canvas_item_owner; - - Map< RID, Set<RID> > instance_dependency_map; - Map< RID, Set<Instance*> > skeleton_dependency_map; - - - ViewportRect viewport_rect; - _FORCE_INLINE_ void _instance_draw(Instance *p_instance); - - bool _test_portal_cull(Camera *p_camera, Instance *p_portal_from, Instance *p_portal_to); - void _cull_portal(Camera *p_camera, Instance *p_portal,Instance *p_from_portal); - void _cull_room(Camera *p_camera, Instance *p_room,Instance *p_from_portal=NULL); - void _process_sampled_light(const Transform &p_camera, Instance *p_sampled_light, bool p_linear_colorspace); - - void _render_no_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); - void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); - static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect); - void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Transform2D& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights); - void _render_canvas_item(CanvasItem *p_canvas_item, const Transform2D& p_transform, const Rect2& p_clip_rect, float p_opacity, int p_z, Rasterizer::CanvasItem **z_list, Rasterizer::CanvasItem **z_last_list, CanvasItem *p_canvas_clip, CanvasItem *p_material_owner); - void _render_canvas(Canvas *p_canvas, const Transform2D &p_transform, Rasterizer::CanvasLight *p_lights, Rasterizer::CanvasLight *p_masked_lights); - void _light_mask_canvas_items(int p_z,Rasterizer::CanvasItem *p_canvas_item,Rasterizer::CanvasLight *p_masked_lights); - - Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); - Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); - - void _light_instance_update_lispsm_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range); - void _light_instance_update_pssm_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range); - - void _light_instance_update_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range); - - uint64_t render_pass; - int changes; - bool draw_extra_frame; - - void _draw_viewport_camera(Viewport *p_viewport, bool p_ignore_camera); - void _draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h); - void _draw_viewports(); - void _draw_cursors_and_margins(); - - - Rasterizer *rasterizer; - -#endif - void _draw_margins(); static void _changes_changed() {} public: -//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed() -//#define DEBUG_CHANGES + //if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed() + //#define DEBUG_CHANGES #ifdef DEBUG_CHANGES _FORCE_INLINE_ static void redraw_request() { @@ -611,7 +96,7 @@ public: #define DISPLAY_CHANGED \ changes++; #endif -// print_line(String("CHANGED: ") + __FUNCTION__); + // print_line(String("CHANGED: ") + __FUNCTION__); #define BIND0R(m_r, m_name) \ m_r m_name() { return BINDBASE->m_name(); } @@ -718,7 +203,7 @@ public: BIND0R(RID, mesh_create) - BIND10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const Rect3 &, const Vector<PoolVector<uint8_t> > &, const Vector<Rect3> &) + BIND10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const AABB &, const Vector<PoolVector<uint8_t> > &, const Vector<AABB> &) BIND2(mesh_set_blend_shape_count, RID, int) BIND1RC(int, mesh_get_blend_shape_count, RID) @@ -726,6 +211,8 @@ public: BIND2(mesh_set_blend_shape_mode, RID, BlendShapeMode) BIND1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) + BIND4(mesh_surface_update_region, RID, int, int, const PoolVector<uint8_t> &) + BIND3(mesh_surface_set_material, RID, int, RID) BIND2RC(RID, mesh_surface_get_material, RID, int) @@ -738,15 +225,15 @@ public: BIND2RC(uint32_t, mesh_surface_get_format, RID, int) BIND2RC(PrimitiveType, mesh_surface_get_primitive_type, RID, int) - BIND2RC(Rect3, mesh_surface_get_aabb, RID, int) + BIND2RC(AABB, mesh_surface_get_aabb, RID, int) BIND2RC(Vector<PoolVector<uint8_t> >, mesh_surface_get_blend_shapes, RID, int) - BIND2RC(Vector<Rect3>, mesh_surface_get_skeleton_aabb, RID, int) + BIND2RC(Vector<AABB>, mesh_surface_get_skeleton_aabb, RID, int) BIND2(mesh_remove_surface, RID, int) BIND1RC(int, mesh_get_surface_count, RID) - BIND2(mesh_set_custom_aabb, RID, const Rect3 &) - BIND1RC(Rect3, mesh_get_custom_aabb, RID) + BIND2(mesh_set_custom_aabb, RID, const AABB &) + BIND1RC(AABB, mesh_get_custom_aabb, RID) BIND1(mesh_clear, RID) @@ -763,7 +250,7 @@ public: BIND3(multimesh_instance_set_color, RID, int, const Color &) BIND1RC(RID, multimesh_get_mesh, RID) - BIND1RC(Rect3, multimesh_get_aabb, RID) + BIND1RC(AABB, multimesh_get_aabb, RID) BIND2RC(Transform, multimesh_instance_get_transform, RID, int) BIND2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) @@ -799,7 +286,9 @@ public: /* Light API */ - BIND1R(RID, light_create, LightType) + BIND0R(RID, directional_light_create) + BIND0R(RID, omni_light_create) + BIND0R(RID, spot_light_create) BIND2(light_set_color, RID, const Color &) BIND3(light_set_param, RID, LightParam, float) @@ -838,8 +327,8 @@ public: BIND0R(RID, gi_probe_create) - BIND2(gi_probe_set_bounds, RID, const Rect3 &) - BIND1RC(Rect3, gi_probe_get_bounds, RID) + BIND2(gi_probe_set_bounds, RID, const AABB &) + BIND1RC(AABB, gi_probe_get_bounds, RID) BIND2(gi_probe_set_cell_size, RID, float) BIND1RC(float, gi_probe_get_cell_size, RID) @@ -882,7 +371,7 @@ public: BIND2(particles_set_pre_process_time, RID, float) BIND2(particles_set_explosiveness_ratio, RID, float) BIND2(particles_set_randomness_ratio, RID, float) - BIND2(particles_set_custom_aabb, RID, const Rect3 &) + BIND2(particles_set_custom_aabb, RID, const AABB &) BIND2(particles_set_speed_scale, RID, float) BIND2(particles_set_use_local_coordinates, RID, bool) BIND2(particles_set_process_material, RID, RID) @@ -895,7 +384,7 @@ public: BIND2(particles_set_draw_passes, RID, int) BIND3(particles_set_draw_pass_mesh, RID, int, RID) - BIND1R(Rect3, particles_get_current_aabb, RID) + BIND1R(AABB, particles_get_current_aabb, RID) BIND2(particles_set_emission_transform, RID, const Transform &) #undef BINDBASE @@ -960,7 +449,7 @@ public: BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo) BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw) -/* ENVIRONMENT API */ + /* ENVIRONMENT API */ #undef BINDBASE //from now on, calls forwarded to this singleton @@ -990,7 +479,7 @@ public: BIND6(environment_set_fog_depth, RID, bool, float, float, bool, float) BIND5(environment_set_fog_height, RID, bool, float, float, float) -/* SCENARIO API */ + /* SCENARIO API */ #undef BINDBASE #define BINDBASE VSG::scene @@ -1021,7 +510,7 @@ public: BIND2(instance_set_extra_visibility_margin, RID, real_t) // don't use these in a game! - BIND2RC(Vector<ObjectID>, instances_cull_aabb, const Rect3 &, RID) + BIND2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) BIND3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) BIND2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index e49baf0763..4febd1a61b 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -614,7 +614,7 @@ void VisualServerScene::instance_set_exterior(RID p_instance, bool p_enabled) { void VisualServerScene::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) { } -Vector<ObjectID> VisualServerScene::instances_cull_aabb(const Rect3 &p_aabb, RID p_scenario) const { +Vector<ObjectID> VisualServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.get(p_scenario); @@ -772,7 +772,7 @@ void VisualServerScene::_update_instance(Instance *p_instance) { p_instance->mirror = p_instance->transform.basis.determinant() < 0.0; - Rect3 new_aabb; + AABB new_aabb; new_aabb = p_instance->transform.xform(p_instance->aabb); @@ -817,7 +817,7 @@ void VisualServerScene::_update_instance(Instance *p_instance) { void VisualServerScene::_update_instance_aabb(Instance *p_instance) { - Rect3 new_aabb; + AABB new_aabb; ERR_FAIL_COND(p_instance->base_type != VS::INSTANCE_NONE && !p_instance->base.is_valid()); @@ -1863,7 +1863,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) { probe->dynamic.enabled = true; Transform cell_to_xform = VSG::storage->gi_probe_get_to_cell_xform(p_instance->base); - Rect3 bounds = VSG::storage->gi_probe_get_bounds(p_instance->base); + AABB bounds = VSG::storage->gi_probe_get_bounds(p_instance->base); float cell_size = VSG::storage->gi_probe_get_cell_size(p_instance->base); probe->dynamic.light_to_cell_xform = cell_to_xform * p_instance->transform.affine_inverse(); @@ -2562,7 +2562,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) { InstanceGIProbeData::LightCache lc; lc.type = VSG::storage->light_get_type(E->get()->base); lc.color = VSG::storage->light_get_color(E->get()->base); - lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY); + lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY) * VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_INDIRECT_ENERGY); lc.radius = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_RANGE); lc.attenuation = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ATTENUATION); lc.spot_angle = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_SPOT_ANGLE); @@ -2582,7 +2582,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) { InstanceGIProbeData::LightCache lc; lc.type = VSG::storage->light_get_type(E->get()->base); lc.color = VSG::storage->light_get_color(E->get()->base); - lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY); + lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY) * VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_INDIRECT_ENERGY); lc.radius = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_RANGE); lc.attenuation = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ATTENUATION); lc.spot_angle = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_SPOT_ANGLE); diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index d30a2108a5..2738fa058d 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -195,8 +195,8 @@ public: SelfList<Instance> update_item; - Rect3 aabb; - Rect3 transformed_aabb; + AABB aabb; + AABB transformed_aabb; float extra_margin; uint32_t object_ID; @@ -466,7 +466,7 @@ public: virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin); // don't use these in a game! - virtual Vector<ObjectID> instances_cull_aabb(const Rect3 &p_aabb, RID p_scenario = RID()) const; + virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const; virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const; virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const; diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 92c431e393..fbf593f5b9 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -268,7 +268,7 @@ void VisualServerViewport::draw_viewports() { if (vp->use_arvr && arvr_interface.is_valid()) { // override our size, make sure it matches our required size - Size2 size = arvr_interface->get_recommended_render_targetsize(); + Size2 size = arvr_interface->get_render_targetsize(); VSG::storage->render_target_set_size(vp->render_target, size.x, size.y); // render mono or left eye first diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index d9a0077e60..1a03c72529 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -154,14 +154,34 @@ void VisualServerWrapMT::finish() { Thread::wait_to_finish(thread); memdelete(thread); - texture_free_cached_ids(); - //mesh_free_cached_ids(); - thread = NULL; } else { visual_server->finish(); } + texture_free_cached_ids(); + shader_free_cached_ids(); + material_free_cached_ids(); + mesh_free_cached_ids(); + multimesh_free_cached_ids(); + immediate_free_cached_ids(); + skeleton_free_cached_ids(); + directional_light_free_cached_ids(); + omni_light_free_cached_ids(); + spot_light_free_cached_ids(); + reflection_probe_free_cached_ids(); + gi_probe_free_cached_ids(); + particles_free_cached_ids(); + camera_free_cached_ids(); + viewport_free_cached_ids(); + environment_free_cached_ids(); + scenario_free_cached_ids(); + instance_free_cached_ids(); + canvas_free_cached_ids(); + canvas_item_free_cached_ids(); + canvas_light_occluder_free_cached_ids(); + canvas_occluder_polygon_free_cached_ids(); + if (draw_mutex) memdelete(draw_mutex); } diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 67d503dfca..509b77cf9c 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -63,7 +63,7 @@ class VisualServerWrapMT : public VisualServer { int pool_max_size; -//#define DEBUG_SYNC + //#define DEBUG_SYNC #ifdef DEBUG_SYNC #define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); @@ -103,12 +103,12 @@ public: /* SKY API */ - FUNC0R(RID, sky_create) + FUNCRID(sky) FUNC3(sky_set_texture, RID, RID, int) /* SHADER API */ - FUNC0R(RID, shader_create) + FUNCRID(shader) FUNC2(shader_set_code, RID, const String &) FUNC1RC(String, shader_get_code, RID) @@ -120,7 +120,7 @@ public: /* COMMON MATERIAL API */ - FUNC0R(RID, material_create) + FUNCRID(material) FUNC2(material_set_shader, RID, RID) FUNC1RC(RID, material_get_shader, RID) @@ -134,9 +134,9 @@ public: /* MESH API */ - FUNC0R(RID, mesh_create) + FUNCRID(mesh) - FUNC10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const Rect3 &, const Vector<PoolVector<uint8_t> > &, const Vector<Rect3> &) + FUNC10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const AABB &, const Vector<PoolVector<uint8_t> > &, const Vector<AABB> &) FUNC2(mesh_set_blend_shape_count, RID, int) FUNC1RC(int, mesh_get_blend_shape_count, RID) @@ -144,6 +144,8 @@ public: FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode) FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) + FUNC4(mesh_surface_update_region, RID, int, int, const PoolVector<uint8_t> &) + FUNC3(mesh_surface_set_material, RID, int, RID) FUNC2RC(RID, mesh_surface_get_material, RID, int) @@ -156,21 +158,21 @@ public: FUNC2RC(uint32_t, mesh_surface_get_format, RID, int) FUNC2RC(PrimitiveType, mesh_surface_get_primitive_type, RID, int) - FUNC2RC(Rect3, mesh_surface_get_aabb, RID, int) + FUNC2RC(AABB, mesh_surface_get_aabb, RID, int) FUNC2RC(Vector<PoolVector<uint8_t> >, mesh_surface_get_blend_shapes, RID, int) - FUNC2RC(Vector<Rect3>, mesh_surface_get_skeleton_aabb, RID, int) + FUNC2RC(Vector<AABB>, mesh_surface_get_skeleton_aabb, RID, int) FUNC2(mesh_remove_surface, RID, int) FUNC1RC(int, mesh_get_surface_count, RID) - FUNC2(mesh_set_custom_aabb, RID, const Rect3 &) - FUNC1RC(Rect3, mesh_get_custom_aabb, RID) + FUNC2(mesh_set_custom_aabb, RID, const AABB &) + FUNC1RC(AABB, mesh_get_custom_aabb, RID) FUNC1(mesh_clear, RID) /* MULTIMESH API */ - FUNC0R(RID, multimesh_create) + FUNCRID(multimesh) FUNC4(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat) FUNC1RC(int, multimesh_get_instance_count, RID) @@ -181,7 +183,7 @@ public: FUNC3(multimesh_instance_set_color, RID, int, const Color &) FUNC1RC(RID, multimesh_get_mesh, RID) - FUNC1RC(Rect3, multimesh_get_aabb, RID) + FUNC1RC(AABB, multimesh_get_aabb, RID) FUNC2RC(Transform, multimesh_instance_get_transform, RID, int) FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) @@ -192,7 +194,7 @@ public: /* IMMEDIATE API */ - FUNC0R(RID, immediate_create) + FUNCRID(immediate) FUNC3(immediate_begin, RID, PrimitiveType, RID) FUNC2(immediate_vertex, RID, const Vector3 &) FUNC2(immediate_normal, RID, const Vector3 &) @@ -207,7 +209,7 @@ public: /* SKELETON API */ - FUNC0R(RID, skeleton_create) + FUNCRID(skeleton) FUNC3(skeleton_allocate, RID, int, bool) FUNC1RC(int, skeleton_get_bone_count, RID) FUNC3(skeleton_bone_set_transform, RID, int, const Transform &) @@ -217,7 +219,9 @@ public: /* Light API */ - FUNC1R(RID, light_create, LightType) + FUNCRID(directional_light) + FUNCRID(omni_light) + FUNCRID(spot_light) FUNC2(light_set_color, RID, const Color &) FUNC3(light_set_param, RID, LightParam, float) @@ -237,7 +241,7 @@ public: /* PROBE API */ - FUNC0R(RID, reflection_probe_create) + FUNCRID(reflection_probe) FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode) FUNC2(reflection_probe_set_intensity, RID, float) @@ -254,10 +258,10 @@ public: /* BAKED LIGHT API */ - FUNC0R(RID, gi_probe_create) + FUNCRID(gi_probe) - FUNC2(gi_probe_set_bounds, RID, const Rect3 &) - FUNC1RC(Rect3, gi_probe_get_bounds, RID) + FUNC2(gi_probe_set_bounds, RID, const AABB &) + FUNC1RC(AABB, gi_probe_get_bounds, RID) FUNC2(gi_probe_set_cell_size, RID, float) FUNC1RC(float, gi_probe_get_cell_size, RID) @@ -291,7 +295,7 @@ public: /* PARTICLES */ - FUNC0R(RID, particles_create) + FUNCRID(particles) FUNC2(particles_set_emitting, RID, bool) FUNC2(particles_set_amount, RID, int) @@ -300,7 +304,7 @@ public: FUNC2(particles_set_pre_process_time, RID, float) FUNC2(particles_set_explosiveness_ratio, RID, float) FUNC2(particles_set_randomness_ratio, RID, float) - FUNC2(particles_set_custom_aabb, RID, const Rect3 &) + FUNC2(particles_set_custom_aabb, RID, const AABB &) FUNC2(particles_set_speed_scale, RID, float) FUNC2(particles_set_use_local_coordinates, RID, bool) FUNC2(particles_set_process_material, RID, RID) @@ -314,11 +318,11 @@ public: FUNC3(particles_set_draw_pass_mesh, RID, int, RID) FUNC2(particles_set_emission_transform, RID, const Transform &) - FUNC1R(Rect3, particles_get_current_aabb, RID) + FUNC1R(AABB, particles_get_current_aabb, RID) /* CAMERA API */ - FUNC0R(RID, camera_create) + FUNCRID(camera) FUNC4(camera_set_perspective, RID, float, float, float) FUNC4(camera_set_orthogonal, RID, float, float, float) FUNC2(camera_set_transform, RID, const Transform &) @@ -328,7 +332,7 @@ public: /* VIEWPORT TARGET API */ - FUNC0R(RID, viewport_create) + FUNCRID(viewport) FUNC2(viewport_set_use_arvr, RID, bool) @@ -377,7 +381,7 @@ public: /* ENVIRONMENT API */ - FUNC0R(RID, environment_create) + FUNCRID(environment) FUNC2(environment_set_background, RID, EnvironmentBG) FUNC2(environment_set_sky, RID, RID) @@ -401,7 +405,7 @@ public: FUNC6(environment_set_fog_depth, RID, bool, float, float, bool, float) FUNC5(environment_set_fog_height, RID, bool, float, float, float) - FUNC0R(RID, scenario_create) + FUNCRID(scenario) FUNC2(scenario_set_debug, RID, ScenarioDebugMode) FUNC2(scenario_set_environment, RID, RID) @@ -410,7 +414,7 @@ public: /* INSTANCING API */ // from can be mesh, light, area and portal so far. - FUNC0R(RID, instance_create) + FUNCRID(instance) FUNC2(instance_set_base, RID, RID) // from can be mesh, light, poly, area and portal so far. FUNC2(instance_set_scenario, RID, RID) // from can be mesh, light, poly, area and portal so far. @@ -427,7 +431,7 @@ public: FUNC2(instance_set_extra_visibility_margin, RID, real_t) // don't use these in a game! - FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const Rect3 &, RID) + FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) @@ -440,11 +444,11 @@ public: /* CANVAS (2D) */ - FUNC0R(RID, canvas_create) + FUNCRID(canvas) FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &) FUNC2(canvas_set_modulate, RID, const Color &) - FUNC0R(RID, canvas_item_create) + FUNCRID(canvas_item) FUNC2(canvas_item_set_parent, RID, RID) FUNC2(canvas_item_set_visible, RID, bool) @@ -510,14 +514,14 @@ public: FUNC2(canvas_light_set_shadow_color, RID, const Color &) FUNC2(canvas_light_set_shadow_smooth, RID, float) - FUNC0R(RID, canvas_light_occluder_create) + FUNCRID(canvas_light_occluder) FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID) FUNC2(canvas_light_occluder_set_enabled, RID, bool) FUNC2(canvas_light_occluder_set_polygon, RID, RID) FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &) FUNC2(canvas_light_occluder_set_light_mask, RID, int) - FUNC0R(RID, canvas_occluder_polygon_create) + FUNCRID(canvas_occluder_polygon) FUNC3(canvas_occluder_polygon_set_shape, RID, const PoolVector<Vector2> &, bool) FUNC2(canvas_occluder_polygon_set_shape_as_lines, RID, const PoolVector<Vector2> &) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 2234ddda0d..10f350d667 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -308,7 +308,7 @@ RID VisualServer::get_white_texture() { #define SMALL_VEC2 Vector2(0.00001, 0.00001) #define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001) -Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, Rect3 &r_aabb, Vector<Rect3> r_bone_aabb) { +Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> r_bone_aabb) { PoolVector<uint8_t>::Write vw = r_vertex_array.write(); @@ -373,7 +373,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ } } - r_aabb = Rect3(Vector3(aabb.position.x, aabb.position.y, 0), Vector3(aabb.size.x, aabb.size.y, 0)); + r_aabb = AABB(Vector3(aabb.position.x, aabb.position.y, 0), Vector3(aabb.size.x, aabb.size.y, 0)); } else { PoolVector<Vector3> array = p_arrays[ai]; @@ -383,7 +383,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ const Vector3 *src = read.ptr(); // setting vertices means regenerating the AABB - Rect3 aabb; + AABB aabb; if (p_format & ARRAY_COMPRESS_VERTEX) { @@ -395,7 +395,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ if (i == 0) { - aabb = Rect3(src[i], SMALL_VEC3); + aabb = AABB(src[i], SMALL_VEC3); } else { aabb.expand_to(src[i]); @@ -411,7 +411,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ if (i == 0) { - aabb = Rect3(src[i], SMALL_VEC3); + aabb = AABB(src[i], SMALL_VEC3); } else { aabb.expand_to(src[i]); @@ -728,7 +728,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ PoolVector<int>::Read rb = bones.read(); PoolVector<float>::Read rw = weights.read(); - Rect3 *bptr = r_bone_aabb.ptr(); + AABB *bptr = r_bone_aabb.ptr(); for (int i = 0; i < vs; i++) { @@ -743,7 +743,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ if (bptr->size.x < 0) { //first - bptr[idx] = Rect3(v, SMALL_VEC3); + bptr[idx] = AABB(v, SMALL_VEC3); any_valid = true; } else { bptr[idx].expand_to(v); @@ -975,8 +975,8 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim PoolVector<uint8_t> index_array; index_array.resize(index_array_size); - Rect3 aabb; - Vector<Rect3> bone_aabb; + AABB aabb; + Vector<AABB> bone_aabb; Error err = _surface_set_data(p_arrays, format, offsets, total_elem_size, vertex_array, array_len, index_array, index_array_len, aabb, bone_aabb); @@ -993,7 +993,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim vertex_array_shape.resize(array_size); PoolVector<uint8_t> noindex; - Rect3 laabb; + AABB laabb; Error err = _surface_set_data(p_blend_shapes[i], format & ~ARRAY_FORMAT_INDEX, offsets, total_elem_size, vertex_array_shape, array_len, noindex, 0, laabb, bone_aabb); aabb.merge_with(laabb); if (err) { @@ -1470,7 +1470,7 @@ Array VisualServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surfac Array VisualServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const { - Vector<Rect3> vec = VS::get_singleton()->mesh_surface_get_skeleton_aabb(p_mesh, p_surface); + Vector<AABB> vec = VS::get_singleton()->mesh_surface_get_skeleton_aabb(p_mesh, p_surface); Array arr; for (int i = 0; i < vec.size(); i++) { arr[i] = vec[i]; @@ -1856,6 +1856,8 @@ void VisualServer::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_SHADERS); BIND_ENUM_CONSTANT(FEATURE_MULTITHREADED); + + ADD_SIGNAL(MethodInfo("frame_drawn_in_thread")); } void VisualServer::_canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate) { diff --git a/servers/visual_server.h b/servers/visual_server.h index 64ed540501..3edde7ec85 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -60,7 +60,7 @@ protected: RID white_texture; RID test_material; - Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, Rect3 &r_aabb, Vector<Rect3> r_bone_aabb); + Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> r_bone_aabb); static VisualServer *(*create_func)(); static void _bind_methods(); @@ -227,6 +227,7 @@ public: ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, ARRAY_FLAG_USE_16_BIT_BONES = ARRAY_COMPRESS_INDEX << 2, + ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_VERTEX | ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 | ARRAY_COMPRESS_WEIGHTS @@ -246,7 +247,7 @@ public: virtual RID mesh_create() = 0; virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT); - virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<Rect3> &p_bone_aabbs = Vector<Rect3>()) = 0; + virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) = 0; virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount) = 0; virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0; @@ -259,6 +260,8 @@ public: virtual void mesh_set_blend_shape_mode(RID p_mesh, BlendShapeMode p_mode) = 0; virtual BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; + virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) = 0; + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; @@ -274,16 +277,16 @@ public: virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const = 0; virtual PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const = 0; - virtual Rect3 mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; + virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const = 0; - virtual Vector<Rect3> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; + virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; Array _mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const; virtual void mesh_remove_surface(RID p_mesh, int p_index) = 0; virtual int mesh_get_surface_count(RID p_mesh) const = 0; - virtual void mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb) = 0; - virtual Rect3 mesh_get_custom_aabb(RID p_mesh) const = 0; + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; + virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; virtual void mesh_clear(RID p_mesh) = 0; @@ -311,7 +314,7 @@ public: virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0; virtual RID multimesh_get_mesh(RID p_multimesh) const = 0; - virtual Rect3 multimesh_get_aabb(RID p_multimesh) const = 0; + virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0; @@ -357,6 +360,7 @@ public: enum LightParam { LIGHT_PARAM_ENERGY, + LIGHT_PARAM_INDIRECT_ENERGY, LIGHT_PARAM_SPECULAR, LIGHT_PARAM_RANGE, LIGHT_PARAM_ATTENUATION, @@ -373,7 +377,9 @@ public: LIGHT_PARAM_MAX }; - virtual RID light_create(LightType p_type) = 0; + virtual RID directional_light_create() = 0; + virtual RID omni_light_create() = 0; + virtual RID spot_light_create() = 0; virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, LightParam p_param, float p_value) = 0; @@ -444,8 +450,8 @@ public: virtual RID gi_probe_create() = 0; - virtual void gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds) = 0; - virtual Rect3 gi_probe_get_bounds(RID p_probe) const = 0; + virtual void gi_probe_set_bounds(RID p_probe, const AABB &p_bounds) = 0; + virtual AABB gi_probe_get_bounds(RID p_probe) const = 0; virtual void gi_probe_set_cell_size(RID p_probe, float p_range) = 0; virtual float gi_probe_get_cell_size(RID p_probe) const = 0; @@ -488,7 +494,7 @@ public: virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; - virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) = 0; + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0; virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0; virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0; virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; @@ -507,7 +513,7 @@ public: virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0; virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0; - virtual Rect3 particles_get_current_aabb(RID p_particles) = 0; + virtual AABB particles_get_current_aabb(RID p_particles) = 0; virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; //this is only used for 2D, in 3D it's automatic @@ -753,7 +759,7 @@ public: virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0; // don't use these in a game! - virtual Vector<ObjectID> instances_cull_aabb(const Rect3 &p_aabb, RID p_scenario = RID()) const = 0; + virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0; virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0; virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0; @@ -808,7 +814,7 @@ public: virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0; virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0; virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()) = 0; - virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true) = 0; + virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = false) = 0; virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()) = 0; virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0; virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false) = 0; |