summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/audio/audio_stream.cpp1
-rw-r--r--servers/audio/audio_stream.h1
-rw-r--r--servers/audio_server.cpp31
-rw-r--r--servers/audio_server.h6
-rw-r--r--servers/physics/physics_server_sw.cpp5
-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.cpp24
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h3
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h10
-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.h17
-rw-r--r--servers/physics_server.cpp1
-rw-r--r--servers/physics_server.h1
-rw-r--r--servers/server_wrap_mt_common.h9
-rw-r--r--servers/visual/rasterizer.h9
-rw-r--r--servers/visual/shader_language.cpp20
-rw-r--r--servers/visual/shader_language.h6
-rw-r--r--servers/visual/shader_types.cpp82
-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.cpp130
-rw-r--r--servers/visual/visual_server_scene.h5
-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.cpp8
-rw-r--r--servers/visual_server.h18
29 files changed, 467 insertions, 134 deletions
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 0ad30987e7..113f23f8f2 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -89,6 +89,7 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
}
}
}
+
////////////////////////////////
void AudioStream::_bind_methods() {
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index fda4fc2ccc..3312ce1ff6 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -31,6 +31,7 @@
#ifndef AUDIO_STREAM_H
#define AUDIO_STREAM_H
+#include "image.h"
#include "resource.h"
#include "servers/audio/audio_filter_sw.h"
#include "servers/audio_server.h"
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index b08e41301a..69c1318a48 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -235,28 +235,12 @@ 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;
}
-#endif
}
void AudioServer::_mix_step() {
@@ -939,9 +923,6 @@ void AudioServer::finish() {
buses.clear();
}
-void AudioServer::update() {
-}
-
/* MISC config */
void AudioServer::lock() {
@@ -1204,6 +1185,8 @@ AudioServer::AudioServer() {
mix_frames = 0;
channel_count = 0;
to_mix = 0;
+ output_latency = 0;
+ output_latency_ticks = 0;
}
AudioServer::~AudioServer() {
diff --git a/servers/audio_server.h b/servers/audio_server.h
index af2668b69e..f928acc7b5 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -190,6 +190,9 @@ private:
Mutex *audio_data_lock;
+ float output_latency;
+ uint64_t output_latency_ticks;
+
void init_channels_and_buffers();
void _mix_step();
@@ -273,7 +276,6 @@ public:
virtual void init();
virtual void finish();
- virtual void update();
virtual void load_default_bus_layout();
/* MISC config */
@@ -307,6 +309,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/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index f2dbb635f8..6c25ad43f9 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);
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..a473e0beb2 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -962,22 +962,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);
+ 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_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..e5961b9011 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -232,7 +232,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..3119b930d7 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -245,10 +245,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);
+ 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_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..1d04fbc5c6 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -479,7 +479,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..de173491b2 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -664,6 +664,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);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 6712bee8dc..8ecf17c0e6 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"
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..0b37d266e7 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;
@@ -201,6 +201,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 */
@@ -282,19 +283,23 @@ public:
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..92786ea740 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,44 @@ 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.insert("vertex_lighting");
+ shader_modes[VS::SHADER_SPATIAL].modes.push_back("vertex_lighting");
/************ CANVAS ITEM **************************/
@@ -226,17 +228,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 +258,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 04dcde1365..697c890c9a 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1257,6 +1257,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 +1362,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 +1472,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 +1527,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 +1549,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 +1580,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 +1605,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 +1619,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 +1636,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;
@@ -1674,7 +1677,8 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_view
} break;
}
- _render_scene(camera->transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1);
+ _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);
}
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) {
@@ -1684,7 +1688,6 @@ void VisualServerScene::render_camera(Ref<ARVRInterface> &p_interface, ARVRInter
ERR_FAIL_COND(!camera);
/* SETUP CAMERA, we are ignoring type and FOV here */
- bool ortho = false;
float aspect = p_viewport_size.width / (float)p_viewport_size.height;
CameraMatrix camera_matrix = p_interface->get_projection_for_eye(p_eye, aspect, camera->znear, camera->zfar);
@@ -1693,10 +1696,79 @@ void VisualServerScene::render_camera(Ref<ARVRInterface> &p_interface, ARVRInter
Transform world_origin = ARVRServer::get_singleton()->get_world_origin();
Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin);
- _render_scene(cam_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1);
+ // For stereo render we only prepare for our left eye and then reuse the outcome for our right eye
+ if (p_eye == ARVRInterface::EYE_LEFT) {
+ ///@TODO possibly move responsibility for this into our ARVRServer or ARVRInterface?
+
+ // Center our transform, we assume basis is equal.
+ Transform mono_transform = cam_transform;
+ Transform right_transform = p_interface->get_transform_for_eye(ARVRInterface::EYE_RIGHT, world_origin);
+ mono_transform.origin += right_transform.origin;
+ mono_transform.origin *= 0.5;
+
+ // We need to combine our projection frustums for culling.
+ // Ideally we should use our clipping planes for this and combine them,
+ // however our shadow map logic uses our projection matrix.
+ // Note: as our left and right frustums should be mirrored, we don't need our right projection matrix.
+
+ // - get some base values we need
+ float eye_dist = (mono_transform.origin - cam_transform.origin).length();
+ float z_near = camera_matrix.get_z_near(); // get our near plane
+ float z_far = camera_matrix.get_z_far(); // get our far plane
+ float width = (2.0 * z_near) / camera_matrix.matrix[0][0];
+ float x_shift = width * camera_matrix.matrix[2][0];
+ float height = (2.0 * z_near) / camera_matrix.matrix[1][1];
+ float y_shift = height * camera_matrix.matrix[2][1];
+
+ // printf("Eye_dist = %f, Near = %f, Far = %f, Width = %f, Shift = %f\n", eye_dist, z_near, z_far, width, x_shift);
+
+ // - calculate our near plane size (horizontal only, right_near is mirrored)
+ float left_near = -eye_dist - ((width - x_shift) * 0.5);
+
+ // - calculate our far plane size (horizontal only, right_far is mirrored)
+ float left_far = -eye_dist - (z_far * (width - x_shift) * 0.5 / z_near);
+ float left_far_right_eye = eye_dist - (z_far * (width + x_shift) * 0.5 / z_near);
+ if (left_far > left_far_right_eye) {
+ // on displays smaller then double our iod, the right eye far frustrum can overtake the left eyes.
+ left_far = left_far_right_eye;
+ }
+
+ // - figure out required z-shift
+ float slope = (left_far - left_near) / (z_far - z_near);
+ float z_shift = (left_near / slope) - z_near;
+
+ // - figure out new vertical near plane size (this will be slightly oversized thanks to our z-shift)
+ float top_near = (height - y_shift) * 0.5;
+ top_near += (top_near / z_near) * z_shift;
+ float bottom_near = -(height + y_shift) * 0.5;
+ bottom_near += (bottom_near / z_near) * z_shift;
+
+ // printf("Left_near = %f, Left_far = %f, Top_near = %f, Bottom_near = %f, Z_shift = %f\n", left_near, left_far, top_near, bottom_near, z_shift);
+
+ // - generate our frustum
+ CameraMatrix combined_matrix;
+ combined_matrix.set_frustum(left_near, -left_near, bottom_near, top_near, z_near + z_shift, z_far + z_shift);
+
+ // and finally move our camera back
+ Transform apply_z_shift;
+ apply_z_shift.origin = Vector3(0.0, 0.0, z_shift); // z negative is forward so this moves it backwards
+ mono_transform *= apply_z_shift;
+
+ // now prepare our scene with our adjusted transform projection matrix
+ _prepare_scene(mono_transform, combined_matrix, false, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
+ } else if (p_eye == ARVRInterface::EYE_MONO) {
+ // For mono render, prepare as per usual
+ _prepare_scene(cam_transform, camera_matrix, false, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
+ }
+
+ // And render our scene...
+ _render_scene(cam_transform, camera_matrix, false, camera->env, p_scenario, p_shadow_atlas, RID(), -1);
};
-void VisualServerScene::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
+void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe) {
+ // Note, in stereo rendering:
+ // - p_cam_transform will be a transform in the middle of our two eyes
+ // - p_cam_projection is a wider frustrum that encompasses both eyes
Scenario *scenario = scenario_owner.getornull(p_scenario);
@@ -1713,7 +1785,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
float z_far = p_cam_projection.get_z_far();
/* STEP 2 - CULL */
- int cull_count = scenario->octree.cull_convex(planes, instance_cull_result, MAX_INSTANCE_CULL);
+ instance_cull_count = scenario->octree.cull_convex(planes, instance_cull_result, MAX_INSTANCE_CULL);
light_cull_count = 0;
reflection_probe_cull_count = 0;
@@ -1731,7 +1803,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
/* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */
- for (int i = 0; i < cull_count; i++) {
+ for (int i = 0; i < instance_cull_count; i++) {
Instance *ins = instance_cull_result[i];
@@ -1857,8 +1929,8 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
if (!keep) {
// remove, no reason to keep
- cull_count--;
- SWAP(instance_cull_result[i], instance_cull_result[cull_count]);
+ instance_cull_count--;
+ SWAP(instance_cull_result[i], instance_cull_result[instance_cull_count]);
i--;
ins->last_render_pass = 0; // make invalid
} else {
@@ -1870,7 +1942,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
/* STEP 5 - PROCESS LIGHTS */
RID *directional_light_ptr = &light_instance_cull_result[light_cull_count];
- int directional_light_count = 0;
+ directional_light_count = 0;
// directional lights
{
@@ -2007,6 +2079,11 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
}
}
}
+}
+
+void VisualServerScene::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
+
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
/* ENVIRONMENT */
@@ -2018,9 +2095,9 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
else
environment = scenario->fallback_environment;
- /* STEP 6 - PROCESS GEOMETRY AND DRAW SCENE*/
+ /* PROCESS GEOMETRY AND DRAW SCENE */
- VSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
+ VSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
}
void VisualServerScene::render_empty_scene(RID p_scenario, RID p_shadow_atlas) {
@@ -2093,7 +2170,8 @@ bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int
shadow_atlas = scenario->reflection_probe_shadow_atlas;
}
- _render_scene(xform, cm, false, RID(), VSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step);
+ _prepare_scene(xform, cm, false, RID(), VSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance);
+ _render_scene(xform, cm, false, RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step);
} else {
//do roughness postprocess step until it believes it's done
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 109cdf711c..12d732724a 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -434,11 +434,13 @@ public:
}
};
+ int instance_cull_count;
Instance *instance_cull_result[MAX_INSTANCE_CULL];
Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps
Instance *light_cull_result[MAX_LIGHTS_CULLED];
RID light_instance_cull_result[MAX_LIGHTS_CULLED];
int light_cull_count;
+ int directional_light_count;
RID reflection_probe_instance_cull_result[MAX_REFLECTION_PROBES_CULLED];
int reflection_probe_cull_count;
@@ -483,7 +485,8 @@ public:
_FORCE_INLINE_ void _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
- void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
+ void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe);
+ void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
void render_empty_scene(RID p_scenario, RID p_shadow_atlas);
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
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..dffaccc0d4 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1587,19 +1587,22 @@ 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);
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()));
@@ -2143,7 +2146,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..968cb852ed 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
};
@@ -309,13 +310,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 +331,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 +730,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;
@@ -1023,6 +1034,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);