summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/audio/audio_driver_dummy.cpp2
-rw-r--r--servers/audio/audio_rb_resampler.cpp2
-rw-r--r--servers/audio_server.cpp120
-rw-r--r--servers/audio_server.h31
-rw-r--r--servers/physics/body_pair_sw.cpp42
-rw-r--r--servers/physics/body_sw.cpp16
-rw-r--r--servers/physics/body_sw.h8
-rw-r--r--servers/physics/collision_solver_sat.cpp3
-rw-r--r--servers/physics/physics_server_sw.cpp25
-rw-r--r--servers/physics/physics_server_sw.h70
-rw-r--r--servers/physics_2d/body_2d_sw.cpp16
-rw-r--r--servers/physics_2d/body_2d_sw.h8
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp42
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp11
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.h2
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp40
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h7
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h13
-rw-r--r--servers/physics_2d/space_2d_sw.cpp163
-rw-r--r--servers/physics_2d/space_2d_sw.h3
-rw-r--r--servers/physics_2d_server.h30
-rw-r--r--servers/physics_server.cpp5
-rw-r--r--servers/physics_server.h80
-rw-r--r--servers/server_wrap_mt_common.h9
-rw-r--r--servers/visual/rasterizer.h15
-rw-r--r--servers/visual/shader_language.cpp20
-rw-r--r--servers/visual/shader_language.h6
-rw-r--r--servers/visual/shader_types.cpp83
-rw-r--r--servers/visual/shader_types.h6
-rw-r--r--servers/visual/visual_server_raster.cpp5
-rw-r--r--servers/visual/visual_server_raster.h12
-rw-r--r--servers/visual/visual_server_scene.cpp47
-rw-r--r--servers/visual/visual_server_viewport.cpp2
-rw-r--r--servers/visual/visual_server_wrap_mt.h10
-rw-r--r--servers/visual_server.cpp183
-rw-r--r--servers/visual_server.h23
36 files changed, 1014 insertions, 146 deletions
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index 1ca2334392..be36c3b748 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -44,7 +44,7 @@ Error AudioDriverDummy::init() {
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_frames * channels);
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index 9faa4056c3..3414351681 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -100,6 +100,8 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i
if (C == 6) {
+ // FIXME: Lot of unused assignments here, but it seems like intermediate calculations
+ // should be done as for C == 2 (C == 4 also has some unused assignments).
float v0 = rb[(pos * 6) + 0];
float v1 = rb[(pos * 6) + 1];
float v2 = rb[(pos * 6) + 2];
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 8ee43ddc32..ceb843c031 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -117,6 +117,10 @@ AudioDriver::AudioDriver() {
_last_mix_time = 0;
_mix_amount = 0;
+
+#ifdef DEBUG_ENABLED
+ prof_time = 0;
+#endif
}
AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS];
@@ -184,6 +188,10 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
int todo = p_frames;
+#ifdef DEBUG_ENABLED
+ uint64_t prof_ticks = OS::get_singleton()->get_ticks_usec();
+#endif
+
if (channel_count != get_channel_count()) {
// Amount of channels changed due to a device change
// reinitialize the buses channels and buffers
@@ -235,27 +243,15 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
to_mix -= to_copy;
}
-#ifdef DEBUG_ENABLED
- if (OS::get_singleton() && OS::get_singleton()->is_stdout_verbose()) {
- static uint64_t first_ticks = 0;
- static uint64_t last_ticks = 0;
- static uint64_t ticks = 0;
- static int count = 0;
- static int total = 0;
-
- ticks = OS::get_singleton()->get_ticks_msec();
- 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;
- count = 0;
- }
-
- total += ticks - last_ticks;
- count++;
-
- last_ticks = ticks;
+ // Calculate latency for Performance.AUDIO_OUTPUT_LATENCY
+ if (OS::get_singleton()) {
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec();
+ output_latency = (ticks - output_latency_ticks) / 1000000.f;
+ output_latency_ticks = ticks;
}
+
+#ifdef DEBUG_ENABLED
+ prof_time += OS::get_singleton()->get_ticks_usec() - prof_ticks;
#endif
}
@@ -330,6 +326,10 @@ void AudioServer::_mix_step() {
if (!bus->effects[j].enabled)
continue;
+#ifdef DEBUG_ENABLED
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec();
+#endif
+
for (int k = 0; k < bus->channels.size(); k++) {
if (!bus->channels[k].active)
@@ -344,6 +344,10 @@ void AudioServer::_mix_step() {
continue;
SWAP(bus->channels[k].buffer, temp_buffer[k]);
}
+
+#ifdef DEBUG_ENABLED
+ bus->effects[j].prof_time += OS::get_singleton()->get_ticks_usec() - ticks;
+#endif
}
}
@@ -784,6 +788,9 @@ void AudioServer::add_bus_effect(int p_bus, const Ref<AudioEffect> &p_effect, in
fx.effect = p_effect;
//fx.instance=p_effect->instance();
fx.enabled = true;
+#ifdef DEBUG_ENABLED
+ fx.prof_time = 0;
+#endif
if (p_at_pos >= buses[p_bus]->effects.size() || p_at_pos < 0) {
buses[p_bus]->effects.push_back(fx);
@@ -896,8 +903,8 @@ void AudioServer::init_channels_and_buffers() {
void AudioServer::init() {
- channel_disable_threshold_db = GLOBAL_DEF("audio/channel_disable_threshold_db", -60.0);
- channel_disable_frames = float(GLOBAL_DEF("audio/channel_disable_time", 2.0)) * get_mix_rate();
+ channel_disable_threshold_db = GLOBAL_DEF_RST("audio/channel_disable_threshold_db", -60.0);
+ channel_disable_frames = float(GLOBAL_DEF_RST("audio/channel_disable_time", 2.0)) * get_mix_rate();
buffer_size = 1024; //hardcoded for now
init_channels_and_buffers();
@@ -913,7 +920,69 @@ void AudioServer::init() {
set_edited(false); //avoid editors from thinking this was edited
#endif
- GLOBAL_DEF("audio/video_delay_compensation_ms", 0);
+ GLOBAL_DEF_RST("audio/video_delay_compensation_ms", 0);
+}
+
+void AudioServer::update() {
+#ifdef DEBUG_ENABLED
+ if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) {
+
+ // Driver time includes server time + effects times
+ // Server time includes effects times
+ uint64_t driver_time = AudioDriver::get_singleton()->get_profiling_time();
+ uint64_t server_time = prof_time;
+
+ // Substract the server time from the driver time
+ if (driver_time > server_time)
+ driver_time -= server_time;
+
+ Array values;
+
+ for (int i = buses.size() - 1; i >= 0; i--) {
+ Bus *bus = buses[i];
+ if (bus->bypass)
+ continue;
+
+ for (int j = 0; j < bus->effects.size(); j++) {
+ if (!bus->effects[j].enabled)
+ continue;
+
+ values.push_back(String(bus->name) + bus->effects[j].effect->get_name());
+ values.push_back(USEC_TO_SEC(bus->effects[j].prof_time));
+
+ // Substract the effect time from the driver and server times
+ if (driver_time > bus->effects[j].prof_time)
+ driver_time -= bus->effects[j].prof_time;
+ if (server_time > bus->effects[j].prof_time)
+ server_time -= bus->effects[j].prof_time;
+ }
+ }
+
+ values.push_back("audio_server");
+ values.push_back(USEC_TO_SEC(server_time));
+ values.push_back("audio_driver");
+ values.push_back(USEC_TO_SEC(driver_time));
+
+ ScriptDebugger::get_singleton()->add_profiling_frame_data("audio_thread", values);
+ }
+
+ // Reset profiling times
+ for (int i = buses.size() - 1; i >= 0; i--) {
+ Bus *bus = buses[i];
+ if (bus->bypass)
+ continue;
+
+ for (int j = 0; j < bus->effects.size(); j++) {
+ if (!bus->effects[j].enabled)
+ continue;
+
+ bus->effects[j].prof_time = 0;
+ }
+ }
+
+ AudioDriver::get_singleton()->reset_profiling_time();
+ prof_time = 0;
+#endif
}
void AudioServer::load_default_bus_layout() {
@@ -1201,6 +1270,11 @@ AudioServer::AudioServer() {
mix_frames = 0;
channel_count = 0;
to_mix = 0;
+ output_latency = 0;
+ output_latency_ticks = 0;
+#ifdef DEBUG_ENABLED
+ prof_time = 0;
+#endif
}
AudioServer::~AudioServer() {
diff --git a/servers/audio_server.h b/servers/audio_server.h
index b7fcd9c093..258fd1d9b0 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -33,6 +33,7 @@
#include "audio_frame.h"
#include "object.h"
+#include "os/os.h"
#include "servers/audio/audio_effect.h"
#include "variant.h"
@@ -44,10 +45,23 @@ class AudioDriver {
uint64_t _last_mix_time;
uint64_t _mix_amount;
+#ifdef DEBUG_ENABLED
+ uint64_t prof_ticks;
+ uint64_t prof_time;
+#endif
+
protected:
void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true);
void update_mix_time(int p_frames);
+#ifdef DEBUG_ENABLED
+ _FORCE_INLINE_ void start_counting_ticks() { prof_ticks = OS::get_singleton()->get_ticks_usec(); }
+ _FORCE_INLINE_ void stop_counting_ticks() { prof_time += OS::get_singleton()->get_ticks_usec() - prof_ticks; }
+#else
+ _FORCE_INLINE_ void start_counting_ticks() {}
+ _FORCE_INLINE_ void stop_counting_ticks() {}
+#endif
+
public:
double get_mix_time() const; //useful for video -> audio sync
@@ -82,6 +96,11 @@ public:
SpeakerMode get_speaker_mode_by_total_channels(int p_channels) const;
int get_total_channels_by_speaker_mode(SpeakerMode) const;
+#ifdef DEBUG_ENABLED
+ uint64_t get_profiling_time() const { return prof_time; }
+ void reset_profiling_time() { prof_time = 0; }
+#endif
+
AudioDriver();
virtual ~AudioDriver() {}
};
@@ -129,6 +148,9 @@ private:
uint32_t buffer_size;
uint64_t mix_count;
uint64_t mix_frames;
+#ifdef DEBUG_ENABLED
+ uint64_t prof_time;
+#endif
float channel_disable_threshold_db;
uint32_t channel_disable_frames;
@@ -166,6 +188,9 @@ private:
struct Effect {
Ref<AudioEffect> effect;
bool enabled;
+#ifdef DEBUG_ENABLED
+ uint64_t prof_time;
+#endif
};
Vector<Effect> effects;
@@ -190,6 +215,9 @@ private:
Mutex *audio_data_lock;
+ float output_latency;
+ uint64_t output_latency_ticks;
+
void init_channels_and_buffers();
void _mix_step();
@@ -273,6 +301,7 @@ public:
virtual void init();
virtual void finish();
+ virtual void update();
virtual void load_default_bus_layout();
/* MISC config */
@@ -306,6 +335,8 @@ public:
String get_device();
void set_device(String device);
+ float get_output_latency() { return output_latency; }
+
AudioServer();
virtual ~AudioServer();
};
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index 2a6a9e08ae..5a41b621eb 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -211,6 +211,44 @@ bool BodyPairSW::_test_ccd(real_t p_step, BodySW *p_A, int p_shape_A, const Tran
return true;
}
+real_t combine_bounce(BodySW *A, BodySW *B) {
+ const PhysicsServer::CombineMode cm = A->get_bounce_combine_mode();
+
+ switch (cm) {
+ case PhysicsServer::COMBINE_MODE_INHERIT:
+ if (B->get_bounce_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
+ return combine_bounce(B, A);
+ // else use MAX [This is used when the two bodies doesn't use physical material]
+ case PhysicsServer::COMBINE_MODE_MAX:
+ return MAX(A->get_bounce(), B->get_bounce());
+ case PhysicsServer::COMBINE_MODE_MIN:
+ return MIN(A->get_bounce(), B->get_bounce());
+ case PhysicsServer::COMBINE_MODE_MULTIPLY:
+ return A->get_bounce() * B->get_bounce();
+ default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
+ return (A->get_bounce() + B->get_bounce()) / 2;
+ }
+}
+
+real_t combine_friction(BodySW *A, BodySW *B) {
+ const PhysicsServer::CombineMode cm = A->get_friction_combine_mode();
+
+ switch (cm) {
+ case PhysicsServer::COMBINE_MODE_INHERIT:
+ if (B->get_friction_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
+ return combine_friction(B, A);
+ // else use Multiply [This is used when the two bodies doesn't use physical material]
+ case PhysicsServer::COMBINE_MODE_MULTIPLY:
+ return A->get_friction() * B->get_friction();
+ case PhysicsServer::COMBINE_MODE_MAX:
+ return MAX(A->get_friction(), B->get_friction());
+ case PhysicsServer::COMBINE_MODE_MIN:
+ return MIN(A->get_friction(), B->get_friction());
+ default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
+ return (A->get_friction() + B->get_friction()) / 2;
+ }
+}
+
bool BodyPairSW::setup(real_t p_step) {
//cannot collide
@@ -331,7 +369,7 @@ bool BodyPairSW::setup(real_t p_step) {
c.acc_bias_impulse = 0;
c.acc_bias_impulse_center_of_mass = 0;
- c.bounce = MAX(A->get_bounce(), B->get_bounce());
+ c.bounce = combine_bounce(A, B);
if (c.bounce) {
Vector3 crA = A->get_angular_velocity().cross(c.rA);
@@ -421,7 +459,7 @@ void BodyPairSW::solve(real_t p_step) {
//friction impulse
- real_t friction = A->get_friction() * B->get_friction();
+ real_t friction = combine_friction(A, B);
Vector3 lvA = A->get_linear_velocity() + A->get_angular_velocity().cross(c.rA);
Vector3 lvB = B->get_linear_velocity() + B->get_angular_velocity().cross(c.rB);
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index cc9681193c..59f987fc17 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -423,6 +423,22 @@ void BodySW::_compute_area_gravity_and_dampenings(const AreaSW *p_area) {
area_angular_damp += p_area->get_angular_damp();
}
+void BodySW::set_combine_mode(PhysicsServer::BodyParameter p_param, PhysicsServer::CombineMode p_mode) {
+ if (p_param == PhysicsServer::BODY_PARAM_BOUNCE) {
+ bounce_combine_mode = p_mode;
+ } else {
+ friction_combine_mode = p_mode;
+ }
+}
+
+PhysicsServer::CombineMode BodySW::get_combine_mode(PhysicsServer::BodyParameter p_param) const {
+ if (p_param == PhysicsServer::BODY_PARAM_BOUNCE) {
+ return bounce_combine_mode;
+ } else {
+ return friction_combine_mode;
+ }
+}
+
void BodySW::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) {
if (lock) {
locked_axis |= p_axis;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index fd2ab16b84..25eb20f5d8 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -49,6 +49,8 @@ class BodySW : public CollisionObjectSW {
real_t mass;
real_t bounce;
real_t friction;
+ PhysicsServer::CombineMode bounce_combine_mode;
+ PhysicsServer::CombineMode friction_combine_mode;
real_t linear_damp;
real_t angular_damp;
@@ -298,6 +300,12 @@ public:
_FORCE_INLINE_ Vector3 get_gravity() const { return gravity; }
_FORCE_INLINE_ real_t get_bounce() const { return bounce; }
+ void set_combine_mode(PhysicsServer::BodyParameter p_param, PhysicsServer::CombineMode p_mode);
+ PhysicsServer::CombineMode get_combine_mode(PhysicsServer::BodyParameter p_param) const;
+
+ _FORCE_INLINE_ PhysicsServer::CombineMode get_bounce_combine_mode() const { return bounce_combine_mode; }
+ _FORCE_INLINE_ PhysicsServer::CombineMode get_friction_combine_mode() const { return friction_combine_mode; }
+
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock);
bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const;
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index e587485fcb..44b7c9ac34 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -217,8 +217,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
// generate contacts
//Plane plane_A(p_points_A[0],p_points_A[1],p_points_A[2]);
- int added = 0;
-
for (int i = 0; i < clipbuf_len; i++) {
real_t d = plane_B.distance_to(clipbuf_src[i]);
@@ -233,7 +231,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
continue;
p_callback->call(clipbuf_src[i], closest_B);
- added++;
}
}
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index f2dbb635f8..f1e0cbef29 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -65,6 +65,11 @@ RID PhysicsServerSW::shape_create(ShapeType p_shape) {
shape = memnew(CapsuleShapeSW);
} break;
+ case SHAPE_CYLINDER: {
+
+ ERR_EXPLAIN("CylinderShape is not supported in GodotPhysics. Please switch to Bullet in the Project Settings.");
+ ERR_FAIL_V(RID());
+ } break;
case SHAPE_CONVEX_POLYGON: {
shape = memnew(ConvexPolygonShapeSW);
@@ -696,6 +701,20 @@ real_t PhysicsServerSW::body_get_param(RID p_body, BodyParameter p_param) const
return body->get_param(p_param);
};
+void PhysicsServerSW::body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_combine_mode(p_param, p_mode);
+}
+
+PhysicsServer::CombineMode PhysicsServerSW::body_get_combine_mode(RID p_body, BodyParameter p_param) const {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, COMBINE_MODE_INHERIT);
+
+ return body->get_combine_mode(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);
@@ -1362,6 +1381,8 @@ void PhysicsServerSW::init() {
void PhysicsServerSW::step(real_t p_step) {
+#ifndef _3D_DISABLED
+
if (!active)
return;
@@ -1382,6 +1403,7 @@ void PhysicsServerSW::step(real_t p_step) {
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
}
+#endif
}
void PhysicsServerSW::sync(){
@@ -1390,6 +1412,8 @@ void PhysicsServerSW::sync(){
void PhysicsServerSW::flush_queries() {
+#ifndef _3D_DISABLED
+
if (!active)
return;
@@ -1436,6 +1460,7 @@ void PhysicsServerSW::flush_queries() {
ScriptDebugger::get_singleton()->add_profiling_frame_data("physics", values);
}
+#endif
};
void PhysicsServerSW::finish() {
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 3f56ba26d0..7e9700d026 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -188,6 +188,10 @@ 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;
+ /// p_param accept only Bounce and Friction
+ virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode);
+ virtual CombineMode body_get_combine_mode(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;
@@ -230,6 +234,72 @@ public:
// this function only works on physics process, errors and returns null otherwise
virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body);
+ /* SOFT BODY */
+
+ virtual RID soft_body_create(bool p_init_sleeping = false) { return RID(); }
+
+ virtual void soft_body_update_visual_server(RID p_body, class SoftBodyVisualServerHandler *p_visual_server_handler) {}
+
+ virtual void soft_body_set_space(RID p_body, RID p_space) {}
+ virtual RID soft_body_get_space(RID p_body) const { return RID(); }
+
+ virtual void soft_body_set_collision_layer(RID p_body, uint32_t p_layer) {}
+ virtual uint32_t soft_body_get_collision_layer(RID p_body) const { return 0; }
+
+ virtual void soft_body_set_collision_mask(RID p_body, uint32_t p_mask) {}
+ virtual uint32_t soft_body_get_collision_mask(RID p_body) const { return 0; }
+
+ virtual void soft_body_add_collision_exception(RID p_body, RID p_body_b) {}
+ virtual void soft_body_remove_collision_exception(RID p_body, RID p_body_b) {}
+ virtual void soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {}
+
+ virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {}
+ virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const { return Variant(); }
+
+ virtual void soft_body_set_transform(RID p_body, const Transform &p_transform) {}
+ virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const { return Vector3(); }
+
+ virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) {}
+ virtual bool soft_body_is_ray_pickable(RID p_body) const { return false; }
+
+ virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) {}
+ virtual int soft_body_get_simulation_precision(RID p_body) { return 0; }
+
+ virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) {}
+ virtual real_t soft_body_get_total_mass(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) {}
+ virtual real_t soft_body_get_linear_stiffness(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) {}
+ virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) {}
+ virtual real_t soft_body_get_volume_stiffness(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) {}
+ virtual real_t soft_body_get_pressure_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) {}
+ virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) {}
+ virtual real_t soft_body_get_damping_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) {}
+ virtual real_t soft_body_get_drag_coefficient(RID p_body) { return 0.; }
+
+ virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) {}
+
+ virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) {}
+ virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) { return Vector3(); }
+
+ virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const { return Vector3(); }
+
+ virtual void soft_body_remove_all_pinned_points(RID p_body) {}
+ virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {}
+ virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) { return 0; }
+
/* JOINT API */
virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B);
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index aa063d6c1e..fcd2a65ee7 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -405,6 +405,22 @@ void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) {
area_angular_damp += p_area->get_angular_damp();
}
+void Body2DSW::set_combine_mode(Physics2DServer::BodyParameter p_param, Physics2DServer::CombineMode p_mode) {
+ if (p_param == Physics2DServer::BODY_PARAM_BOUNCE) {
+ bounce_combine_mode = p_mode;
+ } else {
+ friction_combine_mode = p_mode;
+ }
+}
+
+Physics2DServer::CombineMode Body2DSW::get_combine_mode(Physics2DServer::BodyParameter p_param) const {
+ if (p_param == Physics2DServer::BODY_PARAM_BOUNCE) {
+ return bounce_combine_mode;
+ } else {
+ return friction_combine_mode;
+ }
+}
+
void Body2DSW::integrate_forces(real_t p_step) {
if (mode == Physics2DServer::BODY_MODE_STATIC)
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 782adf3416..301bd6b299 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -54,6 +54,8 @@ class Body2DSW : public CollisionObject2DSW {
real_t mass;
real_t bounce;
real_t friction;
+ Physics2DServer::CombineMode bounce_combine_mode;
+ Physics2DServer::CombineMode friction_combine_mode;
real_t _inv_mass;
real_t _inv_inertia;
@@ -256,6 +258,12 @@ public:
_FORCE_INLINE_ real_t get_linear_damp() const { return linear_damp; }
_FORCE_INLINE_ real_t get_angular_damp() const { return angular_damp; }
+ void set_combine_mode(Physics2DServer::BodyParameter p_param, Physics2DServer::CombineMode p_mode);
+ Physics2DServer::CombineMode get_combine_mode(Physics2DServer::BodyParameter p_param) const;
+
+ _FORCE_INLINE_ Physics2DServer::CombineMode get_bounce_combine_mode() const { return bounce_combine_mode; }
+ _FORCE_INLINE_ Physics2DServer::CombineMode get_friction_combine_mode() const { return friction_combine_mode; }
+
void integrate_forces(real_t p_step);
void integrate_velocities(real_t p_step);
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 61c0e0063f..be8dcf6fa8 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -219,6 +219,44 @@ bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const
return true;
}
+real_t combine_bounce(Body2DSW *A, Body2DSW *B) {
+ const Physics2DServer::CombineMode cm = A->get_bounce_combine_mode();
+
+ switch (cm) {
+ case Physics2DServer::COMBINE_MODE_INHERIT:
+ if (B->get_bounce_combine_mode() != Physics2DServer::COMBINE_MODE_INHERIT)
+ return combine_bounce(B, A);
+ // else use MAX [This is used when the two bodies doesn't use physical material]
+ case Physics2DServer::COMBINE_MODE_MAX:
+ return MAX(A->get_bounce(), B->get_bounce());
+ case Physics2DServer::COMBINE_MODE_MIN:
+ return MIN(A->get_bounce(), B->get_bounce());
+ case Physics2DServer::COMBINE_MODE_MULTIPLY:
+ return A->get_bounce() * B->get_bounce();
+ default: // Is always Physics2DServer::COMBINE_MODE_AVERAGE:
+ return (A->get_bounce() + B->get_bounce()) / 2;
+ }
+}
+
+real_t combine_friction(Body2DSW *A, Body2DSW *B) {
+ const Physics2DServer::CombineMode cm = A->get_friction_combine_mode();
+
+ switch (cm) {
+ case Physics2DServer::COMBINE_MODE_INHERIT:
+ if (B->get_friction_combine_mode() != Physics2DServer::COMBINE_MODE_INHERIT)
+ return combine_friction(B, A);
+ // else use Multiply [This is used when the two bodies doesn't use physical material]
+ case Physics2DServer::COMBINE_MODE_MULTIPLY:
+ return A->get_friction() * B->get_friction();
+ case Physics2DServer::COMBINE_MODE_MAX:
+ return MAX(A->get_friction(), B->get_friction());
+ case Physics2DServer::COMBINE_MODE_MIN:
+ return MIN(A->get_friction(), B->get_friction());
+ default: // Is always Physics2DServer::COMBINE_MODE_AVERAGE:
+ return (A->get_friction() + B->get_friction()) / 2;
+ }
+}
+
bool BodyPair2DSW::setup(real_t p_step) {
//cannot collide
@@ -432,7 +470,7 @@ bool BodyPair2DSW::setup(real_t p_step) {
#endif
- c.bounce = MAX(A->get_bounce(), B->get_bounce());
+ c.bounce = combine_bounce(A, B);
if (c.bounce) {
Vector2 crA(-A->get_angular_velocity() * c.rA.y, A->get_angular_velocity() * c.rA.x);
@@ -488,7 +526,7 @@ void BodyPair2DSW::solve(real_t p_step) {
real_t jnOld = c.acc_normal_impulse;
c.acc_normal_impulse = MAX(jnOld + jn, 0.0f);
- real_t friction = A->get_friction() * B->get_friction();
+ real_t friction = combine_friction(A, B);
real_t jtMax = friction * c.acc_normal_impulse;
real_t jt = -vt * c.mass_tangent;
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index efee98a35a..6ce019f36e 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -72,7 +72,7 @@ bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Tr
return found;
}
-bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis) {
+bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis) {
const RayShape2DSW *ray = static_cast<const RayShape2DSW *>(p_shape_A);
if (p_shape_B->get_type() == Physics2DServer::SHAPE_RAY)
@@ -80,6 +80,11 @@ bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Transf
Vector2 from = p_transform_A.get_origin();
Vector2 to = from + p_transform_A[1] * ray->get_length();
+ if (p_motion_A != Vector2()) {
+ //not the best but should be enough
+ Vector2 normal = (to - from).normalized();
+ to += normal * MAX(0.0, normal.dot(p_motion_A));
+ }
Vector2 support_A = to;
Transform2D invb = p_transform_B.affine_inverse();
@@ -270,9 +275,9 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
}
if (swap) {
- return solve_raycast(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, sep_axis);
+ return solve_raycast(p_shape_B, p_motion_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, sep_axis);
} else {
- return solve_raycast(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, sep_axis);
+ return solve_raycast(p_shape_A, p_motion_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, sep_axis);
}
} else if (concave_B) {
diff --git a/servers/physics_2d/collision_solver_2d_sw.h b/servers/physics_2d/collision_solver_2d_sw.h
index e39c41fb75..6faa166115 100644
--- a/servers/physics_2d/collision_solver_2d_sw.h
+++ b/servers/physics_2d/collision_solver_2d_sw.h
@@ -41,7 +41,7 @@ private:
static bool solve_static_line(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result);
static void concave_callback(void *p_userdata, Shape2DSW *p_convex);
static bool solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0);
- static bool solve_raycast(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = NULL);
+ static bool solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = NULL);
public:
static bool solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0);
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index a14fed8184..cfcef8cb04 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -789,6 +789,22 @@ real_t Physics2DServerSW::body_get_param(RID p_body, BodyParameter p_param) cons
return body->get_param(p_param);
};
+void Physics2DServerSW::body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_combine_mode(p_param, p_mode);
+}
+
+Physics2DServer::CombineMode Physics2DServerSW::body_get_combine_mode(RID p_body, BodyParameter p_param) const {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, COMBINE_MODE_INHERIT);
+
+ return body->get_combine_mode(p_param);
+}
+
void Physics2DServerSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
Body2DSW *body = body_owner.get(p_body);
@@ -962,22 +978,40 @@ void Physics2DServerSW::body_set_pickable(RID p_body, bool p_pickable) {
body->set_pickable(p_pickable);
}
-bool Physics2DServerSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result) {
+bool Physics2DServerSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes) {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, false);
+ ERR_FAIL_COND_V(!body->get_space(), false);
+ ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
+
+ return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
+}
+
+int Physics2DServerSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
- return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result);
+ return body->get_space()->test_body_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
}
Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
+ if ((using_threads && !doing_sync)) {
+ ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
+ ERR_FAIL_V(NULL);
+ }
+
+ if (!body_owner.owns(p_body))
+ return NULL;
+
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, NULL);
- if ((using_threads && !doing_sync) || body->get_space()->is_locked()) {
+ if (body->get_space()->is_locked()) {
ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
ERR_FAIL_V(NULL);
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index 036eb934e1..bf00746063 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -200,6 +200,10 @@ 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;
+ /// p_param accept only Bounce and Friction
+ virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode);
+ virtual CombineMode body_get_combine_mode(RID p_body, BodyParameter p_param) 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;
@@ -232,7 +236,8 @@ public:
virtual void body_set_pickable(RID p_body, bool p_pickable);
- virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL);
+ virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true);
+ virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001);
// this function only works on physics process, errors and returns null otherwise
virtual Physics2DDirectBodyState *body_get_direct_state(RID p_body);
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index a15e8bde8b..a85cd5ef8d 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -211,6 +211,9 @@ public:
FUNC3(body_set_param, RID, BodyParameter, real_t);
FUNC2RC(real_t, body_get_param, RID, BodyParameter);
+ FUNC3(body_set_combine_mode, RID, BodyParameter, CombineMode);
+ FUNC2RC(CombineMode, body_get_combine_mode, RID, BodyParameter);
+
FUNC3(body_set_state, RID, BodyState, const Variant &);
FUNC2RC(Variant, body_get_state, RID, BodyState);
@@ -245,10 +248,16 @@ public:
FUNC2(body_set_pickable, RID, bool);
- bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL) {
+ bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) {
+
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
+ }
+
+ int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
- return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result);
+ return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
}
// this function only works on physics process, errors and returns null otherwise
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 0e1f74d8d0..6e45951f42 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -487,7 +487,156 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
return amount;
}
-bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result) {
+int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, Physics2DServer::SeparationResult *r_results, int p_result_max, real_t p_margin) {
+
+ Rect2 body_aabb;
+
+ for (int i = 0; i < p_body->get_shape_count(); i++) {
+
+ if (i == 0)
+ body_aabb = p_body->get_shape_aabb(i);
+ else
+ body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
+ }
+
+ // Undo the currently transform the physics server is aware of and apply the provided one
+ body_aabb = p_transform.xform(p_body->get_inv_transform().xform(body_aabb));
+ body_aabb = body_aabb.grow(p_margin);
+
+ Transform2D body_transform = p_transform;
+
+ for (int i = 0; i < p_result_max; i++) {
+ //reset results
+ r_results[i].collision_depth = 0;
+ }
+
+ int rays_found = 0;
+
+ {
+ // raycast AND separate
+
+ const int max_results = 32;
+ int recover_attempts = 4;
+ Vector2 sr[max_results * 2];
+ Physics2DServerSW::CollCbkData cbk;
+ cbk.max = max_results;
+ Physics2DServerSW::CollCbkData *cbkptr = &cbk;
+ CollisionSolver2DSW::CallbackResult cbkres = Physics2DServerSW::_shape_col_cbk;
+
+ do {
+
+ Vector2 recover_motion;
+
+ bool collided = false;
+
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+ int ray_index = 0;
+
+ for (int j = 0; j < p_body->get_shape_count(); j++) {
+ if (p_body->is_shape_set_as_disabled(j))
+ continue;
+
+ Shape2DSW *body_shape = p_body->get_shape(j);
+
+ if (body_shape->get_type() != Physics2DServer::SHAPE_RAY)
+ continue;
+
+ Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
+
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObject2DSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ cbk.amount = 0;
+ cbk.ptr = sr;
+ cbk.invalid_by_dir = 0;
+
+ if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
+ const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
+ if (p_infinite_inertia && Physics2DServer::BODY_MODE_STATIC != b->get_mode() && Physics2DServer::BODY_MODE_KINEMATIC != b->get_mode()) {
+ continue;
+ }
+ }
+
+ if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
+
+ cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ cbk.valid_depth = p_margin; //only valid depth is the collision margin
+ cbk.invalid_by_dir = 0;
+
+ } else {
+ cbk.valid_dir = Vector2();
+ cbk.valid_depth = 0;
+ cbk.invalid_by_dir = 0;
+ }
+
+ Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
+ if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
+ if (cbk.amount > 0) {
+ collided = true;
+ }
+
+ if (ray_index < p_result_max) {
+ Physics2DServer::SeparationResult &result = r_results[ray_index];
+
+ for (int k = 0; k < cbk.amount; k++) {
+ Vector2 a = sr[k * 2 + 0];
+ Vector2 b = sr[k * 2 + 1];
+
+ recover_motion += (b - a) * 0.4;
+
+ float depth = a.distance_to(b);
+ if (depth > result.collision_depth) {
+
+ result.collision_depth = depth;
+ result.collision_point = b;
+ result.collision_normal = (b - a).normalized();
+ result.collision_local_shape = shape_idx;
+ result.collider = col_obj->get_self();
+ result.collider_id = col_obj->get_instance_id();
+ result.collider_metadata = col_obj->get_shape_metadata(shape_idx);
+ if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
+ Body2DSW *body = (Body2DSW *)col_obj;
+
+ Vector2 rel_vec = b - body->get_transform().get_origin();
+ result.collider_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ray_index++;
+ }
+
+ rays_found = MAX(ray_index, rays_found);
+
+ if (!collided || recover_motion == Vector2()) {
+ break;
+ }
+
+ body_transform.elements[2] += recover_motion;
+ body_aabb.position += recover_motion;
+
+ recover_attempts--;
+ } while (recover_attempts);
+ }
+
+ //optimize results (remove non colliding)
+ for (int i = 0; i < rays_found; i++) {
+ if (r_results[i].collision_depth == 0) {
+ rays_found--;
+ SWAP(r_results[i], r_results[rays_found]);
+ }
+ }
+
+ r_recover_motion = body_transform.elements[2] - p_transform.elements[2];
+ return rays_found;
+}
+
+bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result, bool p_exclude_raycast_shapes) {
//give me back regular physics engine logic
//this is madness
@@ -547,8 +696,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
if (p_body->is_shape_set_as_disabled(j))
continue;
- Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
Shape2DSW *body_shape = p_body->get_shape(j);
+ if (p_exclude_raycast_shapes && body_shape->get_type() == Physics2DServer::SHAPE_RAY) {
+ continue;
+ }
+
+ Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
for (int i = 0; i < amount; i++) {
const CollisionObject2DSW *col_obj = intersection_query_results[i];
@@ -635,8 +788,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
if (p_body->is_shape_set_as_disabled(body_shape_idx))
continue;
- Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(body_shape_idx);
Shape2DSW *body_shape = p_body->get_shape(body_shape_idx);
+ if (p_exclude_raycast_shapes && body_shape->get_type() == Physics2DServer::SHAPE_RAY) {
+ continue;
+ }
+
+ Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(body_shape_idx);
bool stuck = false;
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 79349c46f3..959e15e12d 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -182,7 +182,8 @@ public:
int get_collision_pairs() const { return collision_pairs; }
- bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result);
+ bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result, bool p_exclude_raycast_shapes = true);
+ int test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, Physics2DServer::SeparationResult *r_results, int p_result_max, real_t p_margin);
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); }
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index ba5232f7fe..89c649af49 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -416,6 +416,19 @@ 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;
+ enum CombineMode {
+ COMBINE_MODE_MAX,
+ COMBINE_MODE_MIN,
+ COMBINE_MODE_MULTIPLY,
+ COMBINE_MODE_AVERAGE,
+
+ COMBINE_MODE_INHERIT /// Inherit from other body or use COMBINE_MODE_MAX (Restitution) COMBINE_MODE_MULTIPLY (Friction)
+ };
+
+ /// p_param accept only Bounce and Friction
+ virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) = 0;
+ virtual CombineMode body_get_combine_mode(RID p_body, BodyParameter p_param) const = 0;
+
//state
enum BodyState {
BODY_STATE_TRANSFORM,
@@ -479,7 +492,22 @@ public:
Variant collider_metadata;
};
- virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = NULL) = 0;
+ virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) = 0;
+
+ struct SeparationResult {
+
+ float collision_depth;
+ Vector2 collision_point;
+ Vector2 collision_normal;
+ Vector2 collider_velocity;
+ int collision_local_shape;
+ ObjectID collider_id;
+ RID collider;
+ int collider_shape;
+ Variant collider_metadata;
+ };
+
+ virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0;
/* JOINT API */
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index 82c4eb2e13..b4bd4cb35f 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -400,6 +400,8 @@ void PhysicsShapeQueryResult::_bind_methods() {
void PhysicsServer::_bind_methods() {
+#ifndef _3D_DISABLED
+
ClassDB::bind_method(D_METHOD("shape_create", "type"), &PhysicsServer::shape_create);
ClassDB::bind_method(D_METHOD("shape_set_data", "shape", "data"), &PhysicsServer::shape_set_data);
@@ -664,6 +666,7 @@ void PhysicsServer::_bind_methods() {
BIND_ENUM_CONSTANT(SHAPE_SPHERE);
BIND_ENUM_CONSTANT(SHAPE_BOX);
BIND_ENUM_CONSTANT(SHAPE_CAPSULE);
+ BIND_ENUM_CONSTANT(SHAPE_CYLINDER);
BIND_ENUM_CONSTANT(SHAPE_CONVEX_POLYGON);
BIND_ENUM_CONSTANT(SHAPE_CONCAVE_POLYGON);
BIND_ENUM_CONSTANT(SHAPE_HEIGHTMAP);
@@ -736,6 +739,8 @@ void PhysicsServer::_bind_methods() {
BIND_ENUM_CONSTANT(BODY_AXIS_ANGULAR_X);
BIND_ENUM_CONSTANT(BODY_AXIS_ANGULAR_Y);
BIND_ENUM_CONSTANT(BODY_AXIS_ANGULAR_Z);
+
+#endif
}
PhysicsServer::PhysicsServer() {
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 6712bee8dc..497d23c555 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -228,6 +228,7 @@ public:
SHAPE_SPHERE, ///< float:"radius"
SHAPE_BOX, ///< vec3:"extents"
SHAPE_CAPSULE, ///< dict( float:"radius", float:"height"):capsule
+ SHAPE_CYLINDER, ///< dict( float:"radius", float:"height"):cylinder
SHAPE_CONVEX_POLYGON, ///< array of planes:"planes"
SHAPE_CONCAVE_POLYGON, ///< vector3 array:"triangles" , or Dictionary with "indices" (int array) and "triangles" (Vector3 array)
SHAPE_HEIGHTMAP, ///< dict( int:"width", int:"depth",float:"cell_size", float_array:"heights"
@@ -398,6 +399,19 @@ 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;
+ enum CombineMode {
+ COMBINE_MODE_MAX,
+ COMBINE_MODE_MIN,
+ COMBINE_MODE_MULTIPLY,
+ COMBINE_MODE_AVERAGE,
+
+ COMBINE_MODE_INHERIT /// Inherit from other body or use COMBINE_MODE_MAX (Restitution) COMBINE_MODE_MULTIPLY (Friction)
+ };
+
+ /// p_param accept only Bounce and Friction
+ virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) = 0;
+ virtual CombineMode body_get_combine_mode(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;
@@ -476,6 +490,72 @@ public:
virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL) = 0;
+ /* SOFT BODY */
+
+ virtual RID soft_body_create(bool p_init_sleeping = false) = 0;
+
+ virtual void soft_body_update_visual_server(RID p_body, class SoftBodyVisualServerHandler *p_visual_server_handler) = 0;
+
+ virtual void soft_body_set_space(RID p_body, RID p_space) = 0;
+ virtual RID soft_body_get_space(RID p_body) const = 0;
+
+ virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) = 0;
+
+ virtual void soft_body_set_collision_layer(RID p_body, uint32_t p_layer) = 0;
+ virtual uint32_t soft_body_get_collision_layer(RID p_body) const = 0;
+
+ virtual void soft_body_set_collision_mask(RID p_body, uint32_t p_mask) = 0;
+ virtual uint32_t soft_body_get_collision_mask(RID p_body) const = 0;
+
+ virtual void soft_body_add_collision_exception(RID p_body, RID p_body_b) = 0;
+ virtual void soft_body_remove_collision_exception(RID p_body, RID p_body_b) = 0;
+ virtual void soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) = 0;
+
+ virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) = 0;
+ virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const = 0;
+
+ virtual void soft_body_set_transform(RID p_body, const Transform &p_transform) = 0;
+ virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const = 0;
+
+ virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) = 0;
+ virtual bool soft_body_is_ray_pickable(RID p_body) const = 0;
+
+ virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) = 0;
+ virtual int soft_body_get_simulation_precision(RID p_body) = 0;
+
+ virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) = 0;
+ virtual real_t soft_body_get_total_mass(RID p_body) = 0;
+
+ virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) = 0;
+ virtual real_t soft_body_get_linear_stiffness(RID p_body) = 0;
+
+ virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) = 0;
+ virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) = 0;
+
+ virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) = 0;
+ virtual real_t soft_body_get_volume_stiffness(RID p_body) = 0;
+
+ virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) = 0;
+ virtual real_t soft_body_get_pressure_coefficient(RID p_body) = 0;
+
+ virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) = 0;
+ virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) = 0;
+
+ virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) = 0;
+ virtual real_t soft_body_get_damping_coefficient(RID p_body) = 0;
+
+ virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) = 0;
+ virtual real_t soft_body_get_drag_coefficient(RID p_body) = 0;
+
+ virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) = 0;
+ virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) = 0;
+
+ virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const = 0;
+
+ virtual void soft_body_remove_all_pinned_points(RID p_body) = 0;
+ virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) = 0;
+ virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) = 0;
+
/* JOINT API */
enum JointType {
diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h
index 4681dd46f0..611e25af2a 100644
--- a/servers/server_wrap_mt_common.h
+++ b/servers/server_wrap_mt_common.h
@@ -810,3 +810,12 @@
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
} \
}
+
+#define FUNC13(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13) { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
+ } else { \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
+ } \
+ }
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 8d8e9e693e..a8f4377ce7 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -66,7 +66,7 @@ public:
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0;
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0;
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
@@ -104,10 +104,12 @@ public:
VS::ShadowCastingSetting cast_shadows;
+ //fit in 32 bits
bool mirror : 8;
bool receive_shadows : 8;
bool visible : 8;
- bool baked_light : 8; //this flag is only to know if it actually did use baked light
+ bool baked_light : 4; //this flag is only to know if it actually did use baked light
+ bool redraw_if_visible : 4;
float depth; //used for sorting
@@ -131,6 +133,7 @@ public:
depth_layer = 0;
layer_mask = 1;
baked_light = false;
+ redraw_if_visible = false;
lightmap_capture = NULL;
}
};
@@ -201,6 +204,7 @@ public:
virtual void textures_keep_original(bool p_enable) = 0;
virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
+ virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
/* SKY API */
@@ -276,25 +280,30 @@ public:
virtual AABB mesh_get_custom_aabb(RID p_mesh) 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 */
virtual RID multimesh_create() = 0;
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format) = 0;
+ virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data = VS::MULTIMESH_CUSTOM_DATA_NONE) = 0;
virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0;
virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0;
virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0;
virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0;
+ virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0;
virtual RID multimesh_get_mesh(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;
virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0;
+ virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0;
+
+ virtual void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) = 0;
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 2069e64c43..fd1eb77143 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -2545,7 +2545,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
TkPos pos = _get_tkpos();
tk = _get_token();
- if (tk.type == TK_PERIOD) {
+ if (tk.type == TK_CURSOR) {
+ //do nothing
+ } else if (tk.type == TK_PERIOD) {
StringName identifier;
if (_get_completable_identifier(p_block, COMPLETION_INDEX, identifier)) {
@@ -3583,7 +3585,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
return OK;
}
-Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) {
Token tk = _get_token();
@@ -3642,7 +3644,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- if (!p_render_modes.has(mode)) {
+ if (p_render_modes.find(mode) == -1) {
_set_error("Invalid render mode: '" + String(mode) + "'");
return ERR_PARSE_ERROR;
}
@@ -4097,7 +4099,7 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
return String();
}
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) {
clear();
@@ -4114,7 +4116,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
clear();
@@ -4130,13 +4132,13 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
switch (completion_type) {
case COMPLETION_NONE: {
- //do none
- return ERR_PARSE_ERROR;
+ //do nothing
+ return OK;
} break;
case COMPLETION_RENDER_MODE: {
- for (const Set<String>::Element *E = p_render_modes.front(); E; E = E->next()) {
+ for (int i = 0; i < p_render_modes.size(); i++) {
- r_options->push_back(E->get());
+ r_options->push_back(p_render_modes[i]);
}
return OK;
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index 720511e18d..9b84c5f195 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -650,7 +650,7 @@ private:
Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
- Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
+ Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
public:
//static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
@@ -658,8 +658,8 @@ public:
void clear();
static String get_shader_type(const String &p_code);
- Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
- Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint);
+ Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
+ Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 95193f7a8f..0de8676f32 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -35,7 +35,7 @@ const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(
return shader_modes[p_mode].functions;
}
-const Set<String> &ShaderTypes::get_modes(VS::ShaderMode p_mode) {
+const Vector<StringName> &ShaderTypes::get_modes(VS::ShaderMode p_mode) {
return shader_modes[p_mode].modes;
}
@@ -140,42 +140,45 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["light"].can_discard = true;
- shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_mix");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_add");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_sub");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_mul");
+ //order used puts first enum mode (default) first
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("blend_mix");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("blend_add");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("blend_sub");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("blend_mul");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_opaque");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_always");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_never");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_alpha_prepass");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("depth_draw_opaque");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("depth_draw_always");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("depth_draw_never");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("depth_draw_alpha_prepass");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_test_disable");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("depth_test_disable");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_front");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_back");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_disabled");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("cull_back");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("cull_front");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("cull_disabled");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("unshaded");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert_wrap");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_oren_nayar");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_burley");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_toon");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("diffuse_lambert");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("diffuse_lambert_wrap");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("diffuse_oren_nayar");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("diffuse_burley");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("diffuse_toon");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_schlick_ggx");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_blinn");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_phong");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_toon");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_disabled");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("specular_schlick_ggx");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("specular_blinn");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("specular_phong");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("specular_toon");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("specular_disabled");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_vertex_transform");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("world_vertex_coords");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("skip_vertex_transform");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("world_vertex_coords");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("ensure_correct_normals");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("shadows_disabled");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("shadows_disabled");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("ambient_light_disabled");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("vertex_lighting");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("vertex_lighting");
/************ CANVAS ITEM **************************/
@@ -226,17 +229,17 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].can_discard = true;
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_vertex_transform");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("skip_vertex_transform");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_mix");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_add");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_sub");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_mul");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_premul_alpha");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_disabled");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("blend_mix");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("blend_add");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("blend_sub");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("blend_mul");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("blend_premul_alpha");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("blend_disabled");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("unshaded");
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("light_only");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("unshaded");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("light_only");
/************ PARTICLES **************************/
@@ -256,9 +259,9 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT);
shader_modes[VS::SHADER_PARTICLES].functions["vertex"].can_discard = false;
- shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_force");
- shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_velocity");
- shader_modes[VS::SHADER_PARTICLES].modes.insert("keep_data");
+ shader_modes[VS::SHADER_PARTICLES].modes.push_back("disable_force");
+ shader_modes[VS::SHADER_PARTICLES].modes.push_back("disable_velocity");
+ shader_modes[VS::SHADER_PARTICLES].modes.push_back("keep_data");
shader_types.insert("spatial");
shader_types.insert("canvas_item");
diff --git a/servers/visual/shader_types.h b/servers/visual/shader_types.h
index 1f43ff9c92..0680ec8242 100644
--- a/servers/visual/shader_types.h
+++ b/servers/visual/shader_types.h
@@ -31,14 +31,16 @@
#ifndef SHADERTYPES_H
#define SHADERTYPES_H
+#include "ordered_hash_map.h"
#include "servers/visual_server.h"
#include "shader_language.h"
+
class ShaderTypes {
struct Type {
Map<StringName, ShaderLanguage::FunctionInfo> functions;
- Set<String> modes;
+ Vector<StringName> modes;
};
Map<VS::ShaderMode, Type> shader_modes;
@@ -51,7 +53,7 @@ public:
static ShaderTypes *get_singleton() { return singleton; }
const Map<StringName, ShaderLanguage::FunctionInfo> &get_functions(VS::ShaderMode p_mode);
- const Set<String> &get_modes(VS::ShaderMode p_mode);
+ const Vector<StringName> &get_modes(VS::ShaderMode p_mode);
const Set<String> &get_types();
ShaderTypes();
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index fca3126604..5f207b1d3f 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -95,6 +95,9 @@ void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const Str
void VisualServerRaster::draw(bool p_swap_buffers) {
+ //needs to be done before changes is reset to 0, to not force the editor to redraw
+ VS::get_singleton()->emit_signal("frame_pre_draw");
+
changes = 0;
VSG::rasterizer->begin_frame();
@@ -122,7 +125,7 @@ void VisualServerRaster::draw(bool p_swap_buffers) {
frame_drawn_callbacks.pop_front();
}
- emit_signal("frame_drawn_in_thread");
+ VS::get_singleton()->emit_signal("frame_post_draw");
}
void VisualServerRaster::sync() {
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 8f19de9f8b..ec0d02ed2a 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -139,6 +139,8 @@ public:
void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); }
#define BIND12(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12) \
void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); }
+#define BIND13(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13) \
+ void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); }
//from now on, calls forwarded to this singleton
#define BINDBASE VSG::storage
@@ -171,6 +173,8 @@ public:
BIND2(texture_set_proxy, RID, RID)
+ BIND2(texture_set_force_redraw_if_visible, RID, bool)
+
/* SKY API */
BIND0R(RID, sky_create)
@@ -244,13 +248,14 @@ public:
BIND0R(RID, multimesh_create)
- BIND4(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat)
+ BIND5(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat, MultimeshCustomDataFormat)
BIND1RC(int, multimesh_get_instance_count, RID)
BIND2(multimesh_set_mesh, RID, RID)
BIND3(multimesh_instance_set_transform, RID, int, const Transform &)
BIND3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &)
BIND3(multimesh_instance_set_color, RID, int, const Color &)
+ BIND3(multimesh_instance_set_custom_data, RID, int, const Color &)
BIND1RC(RID, multimesh_get_mesh, RID)
BIND1RC(AABB, multimesh_get_aabb, RID)
@@ -258,6 +263,9 @@ public:
BIND2RC(Transform, multimesh_instance_get_transform, RID, int)
BIND2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int)
BIND2RC(Color, multimesh_instance_get_color, RID, int)
+ BIND2RC(Color, multimesh_instance_get_custom_data, RID, int)
+
+ BIND2(multimesh_set_as_bulk_array, RID, const PoolVector<float> &)
BIND2(multimesh_set_visible_instances, RID, int)
BIND1RC(int, multimesh_get_visible_instances, RID)
@@ -489,7 +497,7 @@ public:
BIND2(environment_set_canvas_max_layer, RID, int)
BIND4(environment_set_ambient_light, RID, const Color &, float, float)
BIND7(environment_set_ssr, RID, bool, int, float, float, float, bool)
- BIND12(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float)
+ BIND13(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float)
BIND6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
BIND6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index b7abb07f43..887cd7429a 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -820,6 +820,11 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
instance->baked_light = p_enabled;
} break;
+ case VS::INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE: {
+
+ instance->redraw_if_visible = p_enabled;
+
+ } break;
}
}
void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) {
@@ -1257,6 +1262,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
+ Transform light_transform = p_instance->transform;
+ light_transform.orthonormalize(); //scale does not count on lights
+
switch (VSG::storage->light_get_type(p_instance->base)) {
case VS::LIGHT_DIRECTIONAL: {
@@ -1359,7 +1367,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
// obtain the light frustm ranges (given endpoints)
- Transform transform = p_instance->transform.orthonormalized(); //discard scale and stabilize light
+ Transform transform = light_transform; //discard scale and stabilize light
Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized();
Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized();
@@ -1469,7 +1477,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
// a pre pass will need to be needed to determine the actual z-near to be used
- Plane near_plane(p_instance->transform.origin, -p_instance->transform.basis.get_axis(2));
+ Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
@@ -1524,14 +1532,14 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
float z = i == 0 ? -1 : 1;
Vector<Plane> planes;
planes.resize(5);
- planes[0] = p_instance->transform.xform(Plane(Vector3(0, 0, z), radius));
- planes[1] = p_instance->transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
- planes[2] = p_instance->transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
- planes[3] = p_instance->transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
- planes[4] = p_instance->transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
+ planes[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
+ planes[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
+ planes[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
+ planes[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
+ planes[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
- Plane near_plane(p_instance->transform.origin, p_instance->transform.basis.get_axis(2) * z);
+ Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
for (int j = 0; j < cull_count; j++) {
@@ -1546,7 +1554,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
}
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), p_instance->transform, radius, 0, i);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i);
VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
}
} break;
@@ -1577,7 +1585,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
Vector3(0, -1, 0)
};
- Transform xform = p_instance->transform * Transform().looking_at(view_normals[i], view_up[i]);
+ Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]);
Vector<Plane> planes = cm.get_projection_planes(xform);
@@ -1602,7 +1610,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
//restore the regular DP matrix
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), p_instance->transform, radius, 0, 0);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0);
} break;
}
@@ -1616,10 +1624,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
CameraMatrix cm;
cm.set_perspective(angle * 2.0, 1.0, 0.01, radius);
- Vector<Plane> planes = cm.get_projection_planes(p_instance->transform);
+ Vector<Plane> planes = cm.get_projection_planes(light_transform);
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
- Plane near_plane(p_instance->transform.origin, -p_instance->transform.basis.get_axis(2));
+ Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
Instance *instance = instance_shadow_cull_result[j];
@@ -1633,7 +1641,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
}
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, p_instance->transform, radius, 0, 0);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0);
VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
} break;
@@ -1641,7 +1649,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
- // render to mono camera
+// render to mono camera
+#ifndef _3D_DISABLED
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
@@ -1676,6 +1685,7 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_view
_prepare_scene(camera->transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
_render_scene(camera->transform, camera_matrix, ortho, camera->env, p_scenario, p_shadow_atlas, RID(), -1);
+#endif
}
void VisualServerScene::render_camera(Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
@@ -1868,6 +1878,10 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
+ if (ins->redraw_if_visible) {
+ VisualServerRaster::redraw_request();
+ }
+
if (ins->base_type == VS::INSTANCE_PARTICLES) {
//particles visible? process them
VSG::storage->particles_request_process(ins->base);
@@ -2099,6 +2113,8 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
void VisualServerScene::render_empty_scene(RID p_scenario, RID p_shadow_atlas) {
+#ifndef _3D_DISABLED
+
Scenario *scenario = scenario_owner.getornull(p_scenario);
RID environment;
@@ -2107,6 +2123,7 @@ void VisualServerScene::render_empty_scene(RID p_scenario, RID p_shadow_atlas) {
else
environment = scenario->fallback_environment;
VSG::scene_render->render_scene(Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
+#endif
}
bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) {
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index dcc270ca5e..dd6bc3cf26 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -268,7 +268,7 @@ void VisualServerViewport::draw_viewports() {
ERR_CONTINUE(!vp->render_target.is_valid());
bool visible = vp->viewport_to_screen_rect != Rect2() || vp->update_mode == VS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == VS::VIEWPORT_UPDATE_ONCE || (vp->update_mode == VS::VIEWPORT_UPDATE_WHEN_VISIBLE && VSG::storage->render_target_was_used(vp->render_target));
- visible = visible && vp->size.x > 0 && vp->size.y > 0;
+ visible = visible && vp->size.x > 1 && vp->size.y > 1;
if (!visible)
continue;
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 19bb58f3ad..48f0ec46f3 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -107,6 +107,8 @@ public:
FUNC2(texture_set_proxy, RID, RID)
+ FUNC2(texture_set_force_redraw_if_visible, RID, bool)
+
/* SKY API */
FUNCRID(sky)
@@ -180,13 +182,14 @@ public:
FUNCRID(multimesh)
- FUNC4(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat)
+ FUNC5(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat, MultimeshCustomDataFormat)
FUNC1RC(int, multimesh_get_instance_count, RID)
FUNC2(multimesh_set_mesh, RID, RID)
FUNC3(multimesh_instance_set_transform, RID, int, const Transform &)
FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &)
FUNC3(multimesh_instance_set_color, RID, int, const Color &)
+ FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &)
FUNC1RC(RID, multimesh_get_mesh, RID)
FUNC1RC(AABB, multimesh_get_aabb, RID)
@@ -194,6 +197,9 @@ public:
FUNC2RC(Transform, multimesh_instance_get_transform, RID, int)
FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int)
FUNC2RC(Color, multimesh_instance_get_color, RID, int)
+ FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int)
+
+ FUNC2(multimesh_set_as_bulk_array, RID, const PoolVector<float> &)
FUNC2(multimesh_set_visible_instances, RID, int)
FUNC1RC(int, multimesh_get_visible_instances, RID)
@@ -416,7 +422,7 @@ public:
FUNC2(environment_set_canvas_max_layer, RID, int)
FUNC4(environment_set_ambient_light, RID, const Color &, float, float)
FUNC7(environment_set_ssr, RID, bool, int, float, float, float, bool)
- FUNC12(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float)
+ FUNC13(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float)
FUNC6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
FUNC6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 21745e87a8..1f3319dc04 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -187,16 +187,14 @@ RID VisualServer::_make_test_cube() {
PoolVector<float> tangents;
PoolVector<Vector3> uvs;
- int vtx_idx = 0;
-#define ADD_VTX(m_idx) \
- vertices.push_back(face_points[m_idx]); \
- normals.push_back(normal_points[m_idx]); \
- tangents.push_back(normal_points[m_idx][1]); \
- tangents.push_back(normal_points[m_idx][2]); \
- tangents.push_back(normal_points[m_idx][0]); \
- tangents.push_back(1.0); \
- uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0)); \
- vtx_idx++;
+#define ADD_VTX(m_idx) \
+ vertices.push_back(face_points[m_idx]); \
+ normals.push_back(normal_points[m_idx]); \
+ tangents.push_back(normal_points[m_idx][1]); \
+ tangents.push_back(normal_points[m_idx][2]); \
+ tangents.push_back(normal_points[m_idx][0]); \
+ tangents.push_back(1.0); \
+ uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0));
for (int i = 0; i < 6; i++) {
@@ -795,6 +793,140 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
return OK;
}
+uint32_t VisualServer::mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const {
+ uint32_t offsets[ARRAY_MAX];
+ mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets);
+ return offsets[p_array_index];
+}
+
+uint32_t VisualServer::mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const {
+ uint32_t offsets[ARRAY_MAX];
+ return mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets);
+}
+
+uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const {
+
+ int total_elem_size = 0;
+
+ for (int i = 0; i < VS::ARRAY_MAX; i++) {
+
+ r_offsets[i] = 0; //reset
+
+ if (!(p_format & (1 << i))) // no array
+ continue;
+
+ int elem_size = 0;
+
+ switch (i) {
+
+ case VS::ARRAY_VERTEX: {
+
+ if (p_format & ARRAY_FLAG_USE_2D_VERTICES) {
+ elem_size = 2;
+ } else {
+ elem_size = 3;
+ }
+
+ if (p_format & ARRAY_COMPRESS_VERTEX) {
+ elem_size *= sizeof(int16_t);
+ } else {
+ elem_size *= sizeof(float);
+ }
+
+ if (elem_size == 6) {
+ elem_size = 8;
+ }
+
+ } break;
+ case VS::ARRAY_NORMAL: {
+
+ if (p_format & ARRAY_COMPRESS_NORMAL) {
+ elem_size = sizeof(uint32_t);
+ } else {
+ elem_size = sizeof(float) * 3;
+ }
+
+ } break;
+
+ case VS::ARRAY_TANGENT: {
+ if (p_format & ARRAY_COMPRESS_TANGENT) {
+ elem_size = sizeof(uint32_t);
+ } else {
+ elem_size = sizeof(float) * 4;
+ }
+
+ } break;
+ case VS::ARRAY_COLOR: {
+
+ if (p_format & ARRAY_COMPRESS_COLOR) {
+ elem_size = sizeof(uint32_t);
+ } else {
+ elem_size = sizeof(float) * 4;
+ }
+ } break;
+ case VS::ARRAY_TEX_UV: {
+ if (p_format & ARRAY_COMPRESS_TEX_UV) {
+ elem_size = sizeof(uint32_t);
+ } else {
+ elem_size = sizeof(float) * 2;
+ }
+
+ } break;
+
+ case VS::ARRAY_TEX_UV2: {
+ if (p_format & ARRAY_COMPRESS_TEX_UV2) {
+ elem_size = sizeof(uint32_t);
+ } else {
+ elem_size = sizeof(float) * 2;
+ }
+
+ } break;
+ case VS::ARRAY_WEIGHTS: {
+
+ if (p_format & ARRAY_COMPRESS_WEIGHTS) {
+ elem_size = sizeof(uint16_t) * 4;
+ } else {
+ elem_size = sizeof(float) * 4;
+ }
+
+ } break;
+ case VS::ARRAY_BONES: {
+
+ if (p_format & ARRAY_FLAG_USE_16_BIT_BONES) {
+ elem_size = sizeof(uint16_t) * 4;
+ } else {
+ elem_size = sizeof(uint32_t);
+ }
+
+ } break;
+ case VS::ARRAY_INDEX: {
+
+ if (p_index_len <= 0) {
+ ERR_PRINT("index_array_len==NO_INDEX_ARRAY");
+ break;
+ }
+ /* determine whether using 16 or 32 bits indices */
+ if (p_vertex_len >= (1 << 16)) {
+
+ elem_size = 4;
+
+ } else {
+ elem_size = 2;
+ }
+ r_offsets[i] = elem_size;
+ continue;
+ } break;
+ default: {
+ ERR_FAIL_V(0);
+ }
+ }
+
+ r_offsets[i] = total_elem_size;
+ total_elem_size += elem_size;
+ }
+ return total_elem_size;
+}
+
void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_compress_format) {
ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX);
@@ -1543,10 +1675,10 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_debug_usage"), &VisualServer::_texture_debug_usage_bind);
ClassDB::bind_method(D_METHOD("textures_keep_original", "enable"), &VisualServer::textures_keep_original);
-
+#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("sky_create"), &VisualServer::sky_create);
ClassDB::bind_method(D_METHOD("sky_set_texture", "sky", "cube_map", "radiance_size"), &VisualServer::sky_set_texture);
-
+#endif
ClassDB::bind_method(D_METHOD("shader_create"), &VisualServer::shader_create);
ClassDB::bind_method(D_METHOD("shader_set_code", "shader", "code"), &VisualServer::shader_set_code);
ClassDB::bind_method(D_METHOD("shader_get_code", "shader"), &VisualServer::shader_get_code);
@@ -1564,11 +1696,14 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("material_set_next_pass", "material", "next_material"), &VisualServer::material_set_next_pass);
ClassDB::bind_method(D_METHOD("mesh_create"), &VisualServer::mesh_create);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_format_offset", "format", "vertex_len", "index_len", "array_index"), &VisualServer::mesh_surface_get_format_offset);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_format_stride", "format", "vertex_len", "index_len"), &VisualServer::mesh_surface_get_format_stride);
ClassDB::bind_method(D_METHOD("mesh_add_surface_from_arrays", "mesh", "primtive", "arrays", "blend_shapes", "compress_format"), &VisualServer::mesh_add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_count", "mesh", "amount"), &VisualServer::mesh_set_blend_shape_count);
ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &VisualServer::mesh_get_blend_shape_count);
ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_mode", "mesh", "mode"), &VisualServer::mesh_set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_mode", "mesh"), &VisualServer::mesh_get_blend_shape_mode);
+ ClassDB::bind_method(D_METHOD("mesh_surface_update_region", "mesh", "surface", "offset", "data"), &VisualServer::mesh_surface_update_region);
ClassDB::bind_method(D_METHOD("mesh_surface_set_material", "mesh", "surface", "material"), &VisualServer::mesh_surface_set_material);
ClassDB::bind_method(D_METHOD("mesh_surface_get_material", "mesh", "surface"), &VisualServer::mesh_surface_get_material);
ClassDB::bind_method(D_METHOD("mesh_surface_get_array_len", "mesh", "surface"), &VisualServer::mesh_surface_get_array_len);
@@ -1587,20 +1722,23 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("mesh_get_custom_aabb", "mesh"), &VisualServer::mesh_get_custom_aabb);
ClassDB::bind_method(D_METHOD("mesh_clear", "mesh"), &VisualServer::mesh_clear);
- ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format"), &VisualServer::multimesh_allocate);
+ ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &VisualServer::multimesh_allocate, DEFVAL(MULTIMESH_CUSTOM_DATA_NONE));
ClassDB::bind_method(D_METHOD("multimesh_get_instance_count", "multimesh"), &VisualServer::multimesh_get_instance_count);
ClassDB::bind_method(D_METHOD("multimesh_set_mesh", "multimesh", "mesh"), &VisualServer::multimesh_set_mesh);
ClassDB::bind_method(D_METHOD("multimesh_instance_set_transform", "multimesh", "index", "transform"), &VisualServer::multimesh_instance_set_transform);
ClassDB::bind_method(D_METHOD("multimesh_instance_set_transform_2d", "multimesh", "index", "transform"), &VisualServer::multimesh_instance_set_transform_2d);
ClassDB::bind_method(D_METHOD("multimesh_instance_set_color", "multimesh", "index", "color"), &VisualServer::multimesh_instance_set_color);
+ ClassDB::bind_method(D_METHOD("multimesh_instance_set_custom_data", "multimesh", "index", "custom_data"), &VisualServer::multimesh_instance_set_custom_data);
ClassDB::bind_method(D_METHOD("multimesh_get_mesh", "multimesh"), &VisualServer::multimesh_get_mesh);
ClassDB::bind_method(D_METHOD("multimesh_get_aabb", "multimesh"), &VisualServer::multimesh_get_aabb);
ClassDB::bind_method(D_METHOD("multimesh_instance_get_transform", "multimesh", "index"), &VisualServer::multimesh_instance_get_transform);
ClassDB::bind_method(D_METHOD("multimesh_instance_get_transform_2d", "multimesh", "index"), &VisualServer::multimesh_instance_get_transform_2d);
ClassDB::bind_method(D_METHOD("multimesh_instance_get_color", "multimesh", "index"), &VisualServer::multimesh_instance_get_color);
+ ClassDB::bind_method(D_METHOD("multimesh_instance_get_custom_data", "multimesh", "index"), &VisualServer::multimesh_instance_get_custom_data);
ClassDB::bind_method(D_METHOD("multimesh_set_visible_instances", "multimesh", "visible"), &VisualServer::multimesh_set_visible_instances);
ClassDB::bind_method(D_METHOD("multimesh_get_visible_instances", "multimesh"), &VisualServer::multimesh_get_visible_instances);
-
+ ClassDB::bind_method(D_METHOD("multimesh_set_as_bulk_array", "multimesh", "array"), &VisualServer::multimesh_set_as_bulk_array);
+#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("immediate_create"), &VisualServer::immediate_create);
ClassDB::bind_method(D_METHOD("immediate_begin", "immediate", "primitive", "texture"), &VisualServer::immediate_begin, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("immediate_vertex", "immediate", "vertex"), &VisualServer::immediate_vertex);
@@ -1614,6 +1752,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("immediate_clear", "immediate"), &VisualServer::immediate_clear);
ClassDB::bind_method(D_METHOD("immediate_set_material", "immediate", "material"), &VisualServer::immediate_set_material);
ClassDB::bind_method(D_METHOD("immediate_get_material", "immediate"), &VisualServer::immediate_get_material);
+#endif
ClassDB::bind_method(D_METHOD("skeleton_create"), &VisualServer::skeleton_create);
ClassDB::bind_method(D_METHOD("skeleton_allocate", "skeleton", "bones", "is_2d_skeleton"), &VisualServer::skeleton_allocate, DEFVAL(false));
@@ -1623,6 +1762,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("skeleton_bone_set_transform_2d", "skeleton", "bone", "transform"), &VisualServer::skeleton_bone_set_transform_2d);
ClassDB::bind_method(D_METHOD("skeleton_bone_get_transform_2d", "skeleton", "bone"), &VisualServer::skeleton_bone_get_transform_2d);
+#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("directional_light_create"), &VisualServer::directional_light_create);
ClassDB::bind_method(D_METHOD("omni_light_create"), &VisualServer::omni_light_create);
ClassDB::bind_method(D_METHOD("spot_light_create"), &VisualServer::spot_light_create);
@@ -1692,7 +1832,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("lightmap_capture_get_octree", "capture"), &VisualServer::lightmap_capture_get_octree);
ClassDB::bind_method(D_METHOD("lightmap_capture_set_energy", "capture", "energy"), &VisualServer::lightmap_capture_set_energy);
ClassDB::bind_method(D_METHOD("lightmap_capture_get_energy", "capture"), &VisualServer::lightmap_capture_get_energy);
-
+#endif
ClassDB::bind_method(D_METHOD("particles_create"), &VisualServer::particles_create);
ClassDB::bind_method(D_METHOD("particles_set_emitting", "particles", "emitting"), &VisualServer::particles_set_emitting);
ClassDB::bind_method(D_METHOD("particles_get_emitting", "particles"), &VisualServer::particles_get_emitting);
@@ -1779,6 +1919,8 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("scenario_set_reflection_atlas_size", "scenario", "p_size", "subdiv"), &VisualServer::scenario_set_reflection_atlas_size);
ClassDB::bind_method(D_METHOD("scenario_set_fallback_environment", "scenario", "environment"), &VisualServer::scenario_set_fallback_environment);
+#ifndef _3D_DISABLED
+
ClassDB::bind_method(D_METHOD("instance_create2", "base", "scenario"), &VisualServer::instance_create2);
ClassDB::bind_method(D_METHOD("instance_create"), &VisualServer::instance_create);
ClassDB::bind_method(D_METHOD("instance_set_base", "instance", "base"), &VisualServer::instance_set_base);
@@ -1803,7 +1945,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("instances_cull_aabb", "aabb", "scenario"), &VisualServer::_instances_cull_aabb_bind, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("instances_cull_ray", "from", "to", "scenario"), &VisualServer::_instances_cull_ray_bind, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("instances_cull_convex", "convex", "scenario"), &VisualServer::_instances_cull_convex_bind, DEFVAL(RID()));
-
+#endif
ClassDB::bind_method(D_METHOD("canvas_create"), &VisualServer::canvas_create);
ClassDB::bind_method(D_METHOD("canvas_set_item_mirroring", "canvas", "item", "mirroring"), &VisualServer::canvas_set_item_mirroring);
ClassDB::bind_method(D_METHOD("canvas_set_modulate", "canvas", "color"), &VisualServer::canvas_set_modulate);
@@ -1886,13 +2028,14 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("init"), &VisualServer::init);
ClassDB::bind_method(D_METHOD("finish"), &VisualServer::finish);
ClassDB::bind_method(D_METHOD("get_render_info", "info"), &VisualServer::get_render_info);
+#ifndef _3D_DISABLED
+ ClassDB::bind_method(D_METHOD("make_sphere_mesh", "latitudes", "longitudes", "radius"), &VisualServer::make_sphere_mesh);
ClassDB::bind_method(D_METHOD("get_test_cube"), &VisualServer::get_test_cube);
+#endif
ClassDB::bind_method(D_METHOD("get_test_texture"), &VisualServer::get_test_texture);
ClassDB::bind_method(D_METHOD("get_white_texture"), &VisualServer::get_white_texture);
- ClassDB::bind_method(D_METHOD("make_sphere_mesh", "latitudes", "longitudes", "radius"), &VisualServer::make_sphere_mesh);
-
ClassDB::bind_method(D_METHOD("set_boot_image", "image", "color", "scale"), &VisualServer::set_boot_image);
ClassDB::bind_method(D_METHOD("set_default_clear_color", "color"), &VisualServer::set_default_clear_color);
@@ -2058,6 +2201,7 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK);
BIND_ENUM_CONSTANT(INSTANCE_FLAG_USE_BAKED_LIGHT);
+ BIND_ENUM_CONSTANT(INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE);
BIND_ENUM_CONSTANT(INSTANCE_FLAG_MAX);
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF);
@@ -2143,7 +2287,8 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_3x3);
- ADD_SIGNAL(MethodInfo("frame_drawn_in_thread"));
+ ADD_SIGNAL(MethodInfo("frame_pre_draw"));
+ ADD_SIGNAL(MethodInfo("frame_post_draw"));
}
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 65d0f07a43..367642b7d4 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -144,6 +144,7 @@ public:
virtual void textures_keep_original(bool p_enable) = 0;
virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
+ virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
/* SKY API */
@@ -233,7 +234,7 @@ public:
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
+ ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 | ARRAY_COMPRESS_WEIGHTS
};
@@ -250,6 +251,10 @@ public:
virtual RID mesh_create() = 0;
+ virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const;
+ virtual uint32_t mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const;
+ /// Returns stride
+ virtual uint32_t mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const;
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 AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) = 0;
@@ -309,13 +314,20 @@ public:
MULTIMESH_COLOR_FLOAT,
};
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, MultimeshColorFormat p_color_format) = 0;
+ enum MultimeshCustomDataFormat {
+ MULTIMESH_CUSTOM_DATA_NONE,
+ MULTIMESH_CUSTOM_DATA_8BIT,
+ MULTIMESH_CUSTOM_DATA_FLOAT,
+ };
+
+ virtual void multimesh_allocate(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, MultimeshColorFormat p_color_format, MultimeshCustomDataFormat p_data_format = MULTIMESH_CUSTOM_DATA_NONE) = 0;
virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0;
virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0;
virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0;
virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0;
+ virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0;
virtual RID multimesh_get_mesh(RID p_multimesh) const = 0;
virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0;
@@ -323,6 +335,9 @@ public:
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;
virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0;
+ virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0;
+
+ virtual void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) = 0;
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
@@ -719,7 +734,7 @@ public:
ENV_SSAO_BLUR_3x3,
};
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, EnvironmentSSAOQuality p_quality, EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, EnvironmentSSAOQuality p_quality, EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
@@ -794,6 +809,7 @@ public:
enum InstanceFlags {
INSTANCE_FLAG_USE_BAKED_LIGHT,
+ INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE,
INSTANCE_FLAG_MAX
};
@@ -1023,6 +1039,7 @@ VARIANT_ENUM_CAST(VisualServer::RenderInfo);
VARIANT_ENUM_CAST(VisualServer::Features);
VARIANT_ENUM_CAST(VisualServer::MultimeshTransformFormat);
VARIANT_ENUM_CAST(VisualServer::MultimeshColorFormat);
+VARIANT_ENUM_CAST(VisualServer::MultimeshCustomDataFormat);
VARIANT_ENUM_CAST(VisualServer::LightOmniShadowMode);
VARIANT_ENUM_CAST(VisualServer::LightOmniShadowDetail);
VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowMode);