summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/arvr_server.cpp52
-rw-r--r--servers/arvr_server.h17
-rw-r--r--servers/audio/audio_stream.cpp1
-rw-r--r--servers/audio/audio_stream.h1
-rw-r--r--servers/audio/effects/audio_effect_compressor.cpp2
-rw-r--r--servers/audio_server.cpp103
-rw-r--r--servers/audio_server.h11
-rw-r--r--servers/physics/body_pair_sw.cpp1
-rw-r--r--servers/physics/collision_object_sw.h3
-rw-r--r--servers/physics/collision_solver_sat.cpp18
-rw-r--r--servers/physics/shape_sw.h2
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp1
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp28
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h5
-rw-r--r--servers/physics_2d/joints_2d_sw.cpp9
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp4
-rw-r--r--servers/physics_2d/space_2d_sw.cpp6
-rw-r--r--servers/physics_2d_server.cpp2
-rw-r--r--servers/physics_server.cpp7
-rw-r--r--servers/physics_server.h3
-rw-r--r--servers/register_server_types.cpp5
-rw-r--r--servers/server_wrap_mt_common.h9
-rw-r--r--servers/visual/rasterizer.h9
-rw-r--r--servers/visual/shader_language.cpp150
-rw-r--r--servers/visual/shader_language.h2
-rw-r--r--servers/visual/shader_types.cpp9
-rw-r--r--servers/visual/visual_server_canvas.cpp18
-rw-r--r--servers/visual/visual_server_canvas.h4
-rw-r--r--servers/visual/visual_server_raster.cpp1
-rw-r--r--servers/visual/visual_server_raster.h9
-rw-r--r--servers/visual/visual_server_scene.cpp136
-rw-r--r--servers/visual/visual_server_scene.h5
-rw-r--r--servers/visual/visual_server_viewport.cpp46
-rw-r--r--servers/visual/visual_server_viewport.h3
-rw-r--r--servers/visual/visual_server_wrap_mt.h7
-rw-r--r--servers/visual_server.cpp11
-rw-r--r--servers/visual_server.h9
37 files changed, 526 insertions, 183 deletions
diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp
index 8620b182df..f48bedbdac 100644
--- a/servers/arvr_server.cpp
+++ b/servers/arvr_server.cpp
@@ -44,6 +44,7 @@ void ARVRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale);
ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame);
ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &ARVRServer::center_on_hmd);
+ ClassDB::bind_method(D_METHOD("get_hmd_transform"), &ARVRServer::get_hmd_transform);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale");
@@ -54,8 +55,15 @@ void ARVRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count);
ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker);
+ ClassDB::bind_method(D_METHOD("get_primary_interface"), &ARVRServer::get_primary_interface);
ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface);
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "primary_interface"), "set_primary_interface", "get_primary_interface");
+
+ ClassDB::bind_method(D_METHOD("get_last_process_usec"), &ARVRServer::get_last_process_usec);
+ ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &ARVRServer::get_last_commit_usec);
+ ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &ARVRServer::get_last_frame_usec);
+
BIND_ENUM_CONSTANT(TRACKER_CONTROLLER);
BIND_ENUM_CONSTANT(TRACKER_BASESTATION);
BIND_ENUM_CONSTANT(TRACKER_ANCHOR);
@@ -132,6 +140,14 @@ void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height)
};
};
+Transform ARVRServer::get_hmd_transform() {
+ Transform hmd_transform;
+ if (primary_interface != NULL) {
+ hmd_transform = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, hmd_transform);
+ };
+ return hmd_transform;
+};
+
void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) {
ERR_FAIL_COND(p_interface.is_null());
@@ -314,6 +330,42 @@ void ARVRServer::clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_
};
};
+uint64_t ARVRServer::get_last_process_usec() {
+ return last_process_usec;
+};
+
+uint64_t ARVRServer::get_last_commit_usec() {
+ return last_commit_usec;
+};
+
+uint64_t ARVRServer::get_last_frame_usec() {
+ return last_frame_usec;
+};
+
+void ARVRServer::_process() {
+ /* called from visual_server_viewport.draw_viewports right before we start drawing our viewports */
+
+ /* mark for our frame timing */
+ last_process_usec = OS::get_singleton()->get_ticks_usec();
+
+ /* process all active interfaces */
+ for (int i = 0; i < interfaces.size(); i++) {
+ if (!interfaces[i].is_valid()) {
+ // ignore, not a valid reference
+ } else if (interfaces[i]->is_initialized()) {
+ interfaces[i]->process();
+ };
+ };
+};
+
+void ARVRServer::_mark_commit() {
+ /* time this */
+ last_commit_usec = OS::get_singleton()->get_ticks_usec();
+
+ /* now store our difference as we may overwrite last_process_usec before this is accessed */
+ last_frame_usec = last_commit_usec - last_process_usec;
+};
+
ARVRServer::ARVRServer() {
singleton = this;
world_scale = 1.0;
diff --git a/servers/arvr_server.h b/servers/arvr_server.h
index 63b7edc73b..1f4d84fe19 100644
--- a/servers/arvr_server.h
+++ b/servers/arvr_server.h
@@ -31,6 +31,7 @@
#ifndef ARVR_SERVER_H
#define ARVR_SERVER_H
+#include "os/os.h"
#include "os/thread_safe.h"
#include "reference.h"
#include "rid.h"
@@ -84,6 +85,10 @@ private:
Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
Transform reference_frame; /* our reference frame */
+ uint64_t last_process_usec; /* for frame timing, usec when we did our processing */
+ uint64_t last_commit_usec; /* for frame timing, usec when we finished committing both eyes */
+ uint64_t last_frame_usec; /* time it took between process and commiting, we should probably average this over the last x frames */
+
protected:
static ARVRServer *singleton;
@@ -134,6 +139,11 @@ public:
void center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height);
/*
+ get_hmd_transform gets our hmd transform (centered between eyes) with most up to date tracking, relative to the origin
+ */
+ Transform get_hmd_transform();
+
+ /*
Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc.
*/
void add_interface(const Ref<ARVRInterface> &p_interface);
@@ -163,6 +173,13 @@ public:
ARVRPositionalTracker *get_tracker(int p_index) const;
ARVRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
+ uint64_t get_last_process_usec();
+ uint64_t get_last_commit_usec();
+ uint64_t get_last_frame_usec();
+
+ void _process();
+ void _mark_commit();
+
ARVRServer();
~ARVRServer();
};
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/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp
index 0252b2f341..8c70b51f8d 100644
--- a/servers/audio/effects/audio_effect_compressor.cpp
+++ b/servers/audio/effects/audio_effect_compressor.cpp
@@ -236,7 +236,7 @@ void AudioEffectCompressor::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "attack_us", PROPERTY_HINT_RANGE, "20,2000,1"), "set_attack_us", "get_attack_us");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "release_ms", PROPERTY_HINT_RANGE, "20,2000,1"), "set_release_ms", "get_release_ms");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_mix", "get_mix");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sidechain", PROPERTY_HINT_ENUM), "set_sidechain", "get_sidechain");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "sidechain", PROPERTY_HINT_ENUM), "set_sidechain", "get_sidechain");
}
AudioEffectCompressor::AudioEffectCompressor() {
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 783788a6a1..f2df7119e7 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -101,6 +101,18 @@ int AudioDriver::get_total_channels_by_speaker_mode(AudioDriver::SpeakerMode p_m
ERR_FAIL_V(2);
}
+Array AudioDriver::get_device_list() {
+ Array list;
+
+ list.push_back("Default");
+
+ return list;
+}
+
+String AudioDriver::get_device() {
+ return "Default";
+}
+
AudioDriver::AudioDriver() {
_last_mix_time = 0;
@@ -172,6 +184,12 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
int todo = p_frames;
+ if (channel_count != get_channel_count()) {
+ // Amount of channels changed due to a device change
+ // reinitialize the buses channels and buffers
+ init_channels_and_buffers();
+ }
+
while (todo) {
if (to_mix == 0) {
@@ -216,29 +234,6 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
todo -= to_copy;
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;
- }
-#endif
}
void AudioServer::_mix_step() {
@@ -485,8 +480,8 @@ void AudioServer::set_bus_count(int p_count) {
}
buses[i] = memnew(Bus);
- buses[i]->channels.resize(get_channel_count());
- for (int j = 0; j < get_channel_count(); j++) {
+ buses[i]->channels.resize(channel_count);
+ for (int j = 0; j < channel_count; j++) {
buses[i]->channels[j].buffer.resize(buffer_size);
}
buses[i]->name = attempt;
@@ -518,6 +513,8 @@ void AudioServer::remove_bus(int p_index) {
memdelete(buses[p_index]);
buses.remove(p_index);
unlock();
+
+ emit_signal("bus_layout_changed");
}
void AudioServer::add_bus(int p_at_pos) {
@@ -555,8 +552,8 @@ void AudioServer::add_bus(int p_at_pos) {
}
Bus *bus = memnew(Bus);
- bus->channels.resize(get_channel_count());
- for (int j = 0; j < get_channel_count(); j++) {
+ bus->channels.resize(channel_count);
+ for (int j = 0; j < channel_count; j++) {
bus->channels[j].buffer.resize(buffer_size);
}
bus->name = attempt;
@@ -571,6 +568,8 @@ void AudioServer::add_bus(int p_at_pos) {
buses.push_back(bus);
else
buses.insert(p_at_pos, bus);
+
+ emit_signal("bus_layout_changed");
}
void AudioServer::move_bus(int p_bus, int p_to_pos) {
@@ -593,6 +592,8 @@ void AudioServer::move_bus(int p_bus, int p_to_pos) {
} else {
buses.insert(p_to_pos - 1, bus);
}
+
+ emit_signal("bus_layout_changed");
}
int AudioServer::get_bus_count() const {
@@ -854,17 +855,29 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const {
return buses[p_bus]->channels[p_channel].active;
}
+void AudioServer::init_channels_and_buffers() {
+ channel_count = get_channel_count();
+ temp_buffer.resize(channel_count);
+
+ for (int i = 0; i < temp_buffer.size(); i++) {
+ temp_buffer[i].resize(buffer_size);
+ }
+
+ for (int i = 0; i < buses.size(); i++) {
+ buses[i]->channels.resize(channel_count);
+ for (int j = 0; j < channel_count; j++) {
+ buses[i]->channels[j].buffer.resize(buffer_size);
+ }
+ }
+}
+
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();
buffer_size = 1024; //hardcoded for now
- temp_buffer.resize(get_channel_count());
-
- for (int i = 0; i < temp_buffer.size(); i++) {
- temp_buffer[i].resize(buffer_size);
- }
+ init_channels_and_buffers();
mix_count = 0;
set_bus_count(1);
@@ -903,9 +916,6 @@ void AudioServer::finish() {
buses.clear();
}
-void AudioServer::update() {
-}
-
/* MISC config */
void AudioServer::lock() {
@@ -1046,8 +1056,8 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
bus_map[bus->name] = bus;
buses[i] = bus;
- buses[i]->channels.resize(get_channel_count());
- for (int j = 0; j < get_channel_count(); j++) {
+ buses[i]->channels.resize(channel_count);
+ for (int j = 0; j < channel_count; j++) {
buses[i]->channels[j].buffer.resize(buffer_size);
}
_update_bus_effects(i);
@@ -1084,6 +1094,21 @@ Ref<AudioBusLayout> AudioServer::generate_bus_layout() const {
return state;
}
+Array AudioServer::get_device_list() {
+
+ return AudioDriver::get_singleton()->get_device_list();
+}
+
+String AudioServer::get_device() {
+
+ return AudioDriver::get_singleton()->get_device();
+}
+
+void AudioServer::set_device(String device) {
+
+ AudioDriver::get_singleton()->set_device(device);
+}
+
void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count);
@@ -1130,6 +1155,9 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_speaker_mode"), &AudioServer::get_speaker_mode);
ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioServer::get_mix_rate);
+ ClassDB::bind_method(D_METHOD("get_device_list"), &AudioServer::get_device_list);
+ ClassDB::bind_method(D_METHOD("get_device"), &AudioServer::get_device);
+ ClassDB::bind_method(D_METHOD("set_device"), &AudioServer::set_device);
ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout);
ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout);
@@ -1148,6 +1176,7 @@ AudioServer::AudioServer() {
audio_data_max_mem = 0;
audio_data_lock = Mutex::create();
mix_frames = 0;
+ channel_count = 0;
to_mix = 0;
}
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 188d38db94..b7fcd9c093 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -70,6 +70,9 @@ public:
virtual void start() = 0;
virtual int get_mix_rate() const = 0;
virtual SpeakerMode get_speaker_mode() const = 0;
+ virtual Array get_device_list();
+ virtual String get_device();
+ virtual void set_device(String device) {}
virtual void lock() = 0;
virtual void unlock() = 0;
virtual void finish() = 0;
@@ -130,6 +133,7 @@ private:
float channel_disable_threshold_db;
uint32_t channel_disable_frames;
+ int channel_count;
int to_mix;
struct Bus {
@@ -186,6 +190,8 @@ private:
Mutex *audio_data_lock;
+ void init_channels_and_buffers();
+
void _mix_step();
struct CallbackItem {
@@ -267,7 +273,6 @@ public:
virtual void init();
virtual void finish();
- virtual void update();
virtual void load_default_bus_layout();
/* MISC config */
@@ -297,6 +302,10 @@ public:
void set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout);
Ref<AudioBusLayout> generate_bus_layout() const;
+ Array get_device_list();
+ String get_device();
+ void set_device(String device);
+
AudioServer();
virtual ~AudioServer();
};
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index 882d201f61..2a6a9e08ae 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -78,6 +78,7 @@ void BodyPairSW::contact_added_callback(const Vector3 &p_point_A, const Vector3
contact.local_A = local_A;
contact.local_B = local_B;
contact.normal = (p_point_A - p_point_B).normalized();
+ contact.mass_normal = 0; // will be computed in setup()
// attempt to determine if the contact will be reused
real_t contact_recycle_radius = space->get_contact_recycle_radius();
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index f5d32e56a0..dee28bb6df 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -37,7 +37,8 @@
#include "shape_sw.h"
#ifdef DEBUG_ENABLED
-#define MAX_OBJECT_DISTANCE 10000000.0
+#define MAX_OBJECT_DISTANCE 3.1622776601683791e+18
+
#define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE * MAX_OBJECT_DISTANCE)
#endif
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index eefb0f0396..e587485fcb 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -341,26 +341,26 @@ public:
min_B -= (max_A - min_A) * 0.5;
max_B += (max_A - min_A) * 0.5;
- real_t dmin = min_B - (min_A + max_A) * 0.5;
- real_t dmax = max_B - (min_A + max_A) * 0.5;
+ min_B -= (min_A + max_A) * 0.5;
+ max_B -= (min_A + max_A) * 0.5;
- if (dmin > 0.0 || dmax < 0.0) {
+ if (min_B > 0.0 || max_B < 0.0) {
separator_axis = axis;
return false; // doesn't contain 0
}
//use the smallest depth
- dmin = Math::abs(dmin);
+ min_B = -min_B;
- if (dmax < dmin) {
- if (dmax < best_depth) {
- best_depth = dmax;
+ if (max_B < min_B) {
+ if (max_B < best_depth) {
+ best_depth = max_B;
best_axis = axis;
}
} else {
- if (dmin < best_depth) {
- best_depth = dmin;
+ if (min_B < best_depth) {
+ best_depth = min_B;
best_axis = -axis; // keep it as A axis
}
}
diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h
index 7f7f9f4f98..7be818b23c 100644
--- a/servers/physics/shape_sw.h
+++ b/servers/physics/shape_sw.h
@@ -240,7 +240,7 @@ public:
_FORCE_INLINE_ real_t get_height() const { return height; }
_FORCE_INLINE_ real_t get_radius() const { return radius; }
- virtual real_t get_area() { return 4.0 / 3.0 * Math_PI * radius * radius * radius + height * Math_PI * radius * radius; }
+ virtual real_t get_area() const { return 4.0 / 3.0 * Math_PI * radius * radius * radius + height * Math_PI * radius * radius; }
virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_CAPSULE; }
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index f51882b5ee..61c0e0063f 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -62,6 +62,7 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto
contact.local_B = local_B;
contact.reused = true;
contact.normal = (p_point_A - p_point_B).normalized();
+ contact.mass_normal = 0; // will be computed in setup()
// attempt to determine if the contact will be reused
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index ce06aa9a2b..23084a4241 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -73,6 +73,27 @@ void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_
_shapes_changed();
}
+void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) {
+ ERR_FAIL_INDEX(p_idx, shapes.size());
+
+ CollisionObject2DSW::Shape &shape = shapes[p_idx];
+ if (shape.disabled == p_disabled)
+ return;
+
+ shape.disabled = p_disabled;
+
+ if (!space)
+ return;
+
+ if (p_disabled && shape.bpid != 0) {
+ space->get_broadphase()->remove(shape.bpid);
+ shape.bpid = 0;
+ _update_shapes();
+ } else if (!p_disabled && shape.bpid == 0) {
+ _update_shapes(); // automatically adds shape with bpid == 0
+ }
+}
+
void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) {
//remove a shape, all the times it appears
@@ -139,6 +160,10 @@ void CollisionObject2DSW::_update_shapes() {
for (int i = 0; i < shapes.size(); i++) {
Shape &s = shapes[i];
+
+ if (s.disabled)
+ continue;
+
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
space->get_broadphase()->set_static(s.bpid, _static);
@@ -163,6 +188,9 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) {
for (int i = 0; i < shapes.size(); i++) {
Shape &s = shapes[i];
+ if (s.disabled)
+ continue;
+
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
space->get_broadphase()->set_static(s.bpid, _static);
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index 5f25c27158..ab3e219ac0 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -136,10 +136,7 @@ public:
_FORCE_INLINE_ Transform2D get_inv_transform() const { return inv_transform; }
_FORCE_INLINE_ Space2DSW *get_space() const { return space; }
- _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_disabled) {
- ERR_FAIL_INDEX(p_idx, shapes.size());
- shapes[p_idx].disabled = p_disabled;
- }
+ void set_shape_as_disabled(int p_idx, bool p_disabled);
_FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, shapes.size(), false);
return shapes[p_idx].disabled;
diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp
index 7fba8acebd..d49c1b8376 100644
--- a/servers/physics_2d/joints_2d_sw.cpp
+++ b/servers/physics_2d/joints_2d_sw.cpp
@@ -146,14 +146,19 @@ bool PinJoint2DSW::setup(real_t p_step) {
return true;
}
+inline Vector2 custom_cross(const Vector2 &p_vec, real_t p_other) {
+
+ return Vector2(p_other * p_vec.y, -p_other * p_vec.x);
+}
+
void PinJoint2DSW::solve(real_t p_step) {
// compute relative velocity
- Vector2 vA = A->get_linear_velocity() - rA.cross(A->get_angular_velocity());
+ Vector2 vA = A->get_linear_velocity() - custom_cross(rA, A->get_angular_velocity());
Vector2 rel_vel;
if (B)
- rel_vel = B->get_linear_velocity() - rB.cross(B->get_angular_velocity()) - vA;
+ rel_vel = B->get_linear_velocity() - custom_cross(rB, B->get_angular_velocity()) - vA;
else
rel_vel = -vA;
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index 433942708e..2b0eab5999 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -1011,6 +1011,10 @@ void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callbac
stack[i]=0;
*/
+ if (segments.size() == 0 || points.size() == 0 || bvh.size() == 0) {
+ return;
+ }
+
int level = 0;
const Segment *segmentptr = &segments[0];
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index c29093d1af..0e1f74d8d0 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -33,6 +33,7 @@
#include "collision_solver_2d_sw.h"
#include "pair.h"
#include "physics_2d_server_sw.h"
+
_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask) {
return p_object->get_collision_layer() & p_collision_mask;
@@ -180,12 +181,15 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans
Rect2 aabb = p_xform.xform(shape->get_aabb());
aabb = aabb.grow(p_margin);
- int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, p_result_max, space->intersection_query_subindex_results);
+ int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
int cc = 0;
for (int i = 0; i < amount; i++) {
+ if (cc >= p_result_max)
+ break;
+
if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
continue;
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index fafc239c7f..cb7669ec24 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -540,6 +540,8 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &Physics2DServer::area_get_object_instance_id);
ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_area_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &Physics2DServer::area_set_monitorable);
ClassDB::bind_method(D_METHOD("body_create"), &Physics2DServer::body_create);
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index db5e14043c..82c4eb2e13 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -96,7 +96,7 @@ void PhysicsDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState::add_force);
ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState::add_torque);
ClassDB::bind_method(D_METHOD("apply_impulse", "position", "j"), &PhysicsDirectBodyState::apply_impulse);
- ClassDB::bind_method(D_METHOD("apply_torqe_impulse", "j"), &PhysicsDirectBodyState::apply_torque_impulse);
+ ClassDB::bind_method(D_METHOD("apply_torque_impulse", "j"), &PhysicsDirectBodyState::apply_torque_impulse);
ClassDB::bind_method(D_METHOD("set_sleep_state", "enabled"), &PhysicsDirectBodyState::set_sleep_state);
ClassDB::bind_method(D_METHOD("is_sleeping"), &PhysicsDirectBodyState::is_sleeping);
@@ -444,6 +444,8 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &PhysicsServer::area_get_object_instance_id);
ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &PhysicsServer::area_set_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &PhysicsServer::area_set_area_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer::area_set_monitorable);
ClassDB::bind_method(D_METHOD("area_set_ray_pickable", "area", "enable"), &PhysicsServer::area_set_ray_pickable);
ClassDB::bind_method(D_METHOD("area_is_ray_pickable", "area"), &PhysicsServer::area_is_ray_pickable);
@@ -603,6 +605,8 @@ void PhysicsServer::_bind_methods() {
BIND_ENUM_CONSTANT(G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS);
BIND_ENUM_CONSTANT(G6DOF_JOINT_LINEAR_RESTITUTION);
BIND_ENUM_CONSTANT(G6DOF_JOINT_LINEAR_DAMPING);
+ BIND_ENUM_CONSTANT(G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY);
+ BIND_ENUM_CONSTANT(G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT);
BIND_ENUM_CONSTANT(G6DOF_JOINT_ANGULAR_LOWER_LIMIT);
BIND_ENUM_CONSTANT(G6DOF_JOINT_ANGULAR_UPPER_LIMIT);
BIND_ENUM_CONSTANT(G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS);
@@ -616,6 +620,7 @@ void PhysicsServer::_bind_methods() {
BIND_ENUM_CONSTANT(G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT);
BIND_ENUM_CONSTANT(G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT);
BIND_ENUM_CONSTANT(G6DOF_JOINT_FLAG_ENABLE_MOTOR);
+ BIND_ENUM_CONSTANT(G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR);
ClassDB::bind_method(D_METHOD("joint_get_type", "joint"), &PhysicsServer::joint_get_type);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 6a342b36d4..6712bee8dc 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -594,6 +594,8 @@ public:
G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS,
G6DOF_JOINT_LINEAR_RESTITUTION,
G6DOF_JOINT_LINEAR_DAMPING,
+ G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY,
+ G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT,
G6DOF_JOINT_ANGULAR_LOWER_LIMIT,
G6DOF_JOINT_ANGULAR_UPPER_LIMIT,
G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS,
@@ -611,6 +613,7 @@ public:
G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT,
G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT,
G6DOF_JOINT_FLAG_ENABLE_MOTOR,
+ G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR,
G6DOF_JOINT_FLAG_MAX
};
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index aaac32a4f2..1bad7e652b 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -80,6 +80,7 @@ static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsag
ShaderTypes *shader_types = NULL;
PhysicsServer *_createGodotPhysicsCallback() {
+ WARN_PRINT("The GodotPhysics 3D physics engine is deprecated and will be removed in Godot 3.2. You should use the Bullet physics engine instead (configurable in your project settings).");
return memnew(PhysicsServerSW);
}
@@ -163,8 +164,8 @@ void register_server_types() {
GLOBAL_DEF(PhysicsServerManager::setting_property_name, "DEFAULT");
ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServerManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
- PhysicsServerManager::register_server("GodotPhysics", &_createGodotPhysicsCallback);
- PhysicsServerManager::set_default_server("GodotPhysics");
+ PhysicsServerManager::register_server("GodotPhysics - deprecated", &_createGodotPhysicsCallback);
+ PhysicsServerManager::set_default_server("GodotPhysics - deprecated");
}
void unregister_server_types() {
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 8bf112b0de..f07adf6d0e 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;
@@ -175,6 +175,7 @@ public:
virtual RID texture_create() = 0;
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT) = 0;
virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
+ virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const = 0;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
@@ -325,6 +326,7 @@ public:
virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
+ virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
/* Light API */
@@ -513,6 +515,7 @@ public:
RENDER_TARGET_NO_3D,
RENDER_TARGET_NO_SAMPLING,
RENDER_TARGET_HDR,
+ RENDER_TARGET_KEEP_3D_LINEAR,
RENDER_TARGET_FLAG_MAX
};
@@ -735,6 +738,8 @@ public:
Vector<Point2> points;
Vector<Point2> uvs;
Vector<Color> colors;
+ Vector<int> bones;
+ Vector<float> weights;
RID texture;
RID normal_map;
int count;
@@ -812,6 +817,8 @@ public:
mutable bool rect_dirty;
mutable Rect2 rect;
RID material;
+ RID skeleton;
+
Item *next;
struct CopyBackBuffer {
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index d9f2c949e9..2069e64c43 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -124,6 +124,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"TYPE_ISAMPLER2D",
"TYPE_USAMPLER2D",
"TYPE_SAMPLERCUBE",
+ "INTERPOLATION_FLAT",
+ "INTERPOLATION_NO_PERSPECTIVE",
+ "INTERPOLATION_SMOOTH",
"PRECISION_LOW",
"PRECISION_MID",
"PRECISION_HIGH",
@@ -1489,11 +1492,6 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID } },
{ "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID } },
- { "abs", TYPE_UINT, { TYPE_UINT, TYPE_VOID } },
- { "abs", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID } },
- { "abs", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID } },
- { "abs", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID } },
-
{ "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
{ "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
{ "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
@@ -1608,7 +1606,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
{ "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
{ "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BOOL, TYPE_VOID } },
- { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC3, TYPE_VOID } },
+ { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID } },
{ "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
{ "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
@@ -1627,24 +1625,24 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID } },
{ "isnan", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID } },
- { "isnan", TYPE_BOOL, { TYPE_VEC2, TYPE_VOID } },
- { "isnan", TYPE_BOOL, { TYPE_VEC3, TYPE_VOID } },
- { "isnan", TYPE_BOOL, { TYPE_VEC4, TYPE_VOID } },
+ { "isnan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID } },
+ { "isnan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID } },
+ { "isnan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID } },
{ "isinf", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID } },
- { "isinf", TYPE_BOOL, { TYPE_VEC2, TYPE_VOID } },
- { "isinf", TYPE_BOOL, { TYPE_VEC3, TYPE_VOID } },
- { "isinf", TYPE_BOOL, { TYPE_VEC4, TYPE_VOID } },
+ { "isinf", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID } },
+ { "isinf", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID } },
+ { "isinf", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID } },
{ "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID } },
{ "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID } },
{ "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID } },
{ "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID } },
- { "floatBitsToUInt", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID } },
- { "floatBitsToUInt", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID } },
- { "floatBitsToUInt", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID } },
- { "floatBitsToUInt", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID } },
+ { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID } },
+ { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID } },
+ { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID } },
+ { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID } },
{ "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID } },
{ "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID } },
@@ -2209,6 +2207,37 @@ ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) {
return scalar_types[p_type];
}
+int ShaderLanguage::get_cardinality(DataType p_type) {
+ static const int cardinality_table[] = {
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 1,
+ 2,
+ 3,
+ 4,
+ 1,
+ 2,
+ 3,
+ 4,
+ 1,
+ 2,
+ 3,
+ 4,
+ 2,
+ 3,
+ 4,
+ 1,
+ 1,
+ 1,
+ 1,
+ };
+
+ return cardinality_table[p_type];
+}
+
bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier) {
identifier = StringName();
@@ -2271,7 +2300,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
if (p_node->type == Node::TYPE_OPERATOR) {
OperatorNode *op = static_cast<OperatorNode *>(p_node);
- if (op->type == OP_INDEX) {
+ if (op->op == OP_INDEX) {
return _validate_assign(op->arguments[0], p_builtin_types);
}
}
@@ -2679,7 +2708,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return NULL;
}
- bool index_valid = false;
DataType member_type = TYPE_VOID;
switch (expr->get_datatype()) {
@@ -2698,7 +2726,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
_set_error("Only integer constants are allowed as index at the moment");
return NULL;
}
- index_valid = true;
+
switch (expr->get_datatype()) {
case TYPE_BVEC2: member_type = TYPE_BOOL; break;
case TYPE_VEC2: member_type = TYPE_FLOAT; break;
@@ -2723,7 +2751,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
_set_error("Only integer constants are allowed as index at the moment");
return NULL;
}
- index_valid = true;
+
switch (expr->get_datatype()) {
case TYPE_BVEC3: member_type = TYPE_BOOL; break;
case TYPE_VEC3: member_type = TYPE_FLOAT; break;
@@ -2747,7 +2775,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
_set_error("Only integer constants are allowed as index at the moment");
return NULL;
}
- index_valid = true;
+
switch (expr->get_datatype()) {
case TYPE_BVEC4: member_type = TYPE_BOOL; break;
case TYPE_VEC4: member_type = TYPE_FLOAT; break;
@@ -2762,11 +2790,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
}
- if (!index_valid) {
- _set_error("Invalid index");
- return NULL;
- }
-
OperatorNode *op = alloc_node<OperatorNode>();
op->op = OP_INDEX;
op->return_cache = member_type;
@@ -2968,7 +2991,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr_pos++;
if (expr_pos == expression.size()) {
//can happen..
- _set_error("Unexpected end of expression..");
+ _set_error("Unexpected end of expression...");
return NULL;
}
}
@@ -3005,12 +3028,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else if (is_ternary) {
if (next_op < 1 || next_op >= (expression.size() - 1)) {
- _set_error("Parser bug..");
+ _set_error("Parser bug...");
ERR_FAIL_V(NULL);
}
if (next_op + 2 >= expression.size() || !expression[next_op + 2].is_op || expression[next_op + 2].op != OP_SELECT_ELSE) {
- _set_error("Mising matching ':' for select operator");
+ _set_error("Missing matching ':' for select operator");
return NULL;
}
@@ -3041,7 +3064,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else {
if (next_op < 1 || next_op >= (expression.size() - 1)) {
- _set_error("Parser bug..");
+ _set_error("Parser bug...");
ERR_FAIL_V(NULL);
}
@@ -3050,7 +3073,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (expression[next_op - 1].is_op) {
- _set_error("Parser bug..");
+ _set_error("Parser bug...");
ERR_FAIL_V(NULL);
}
@@ -3066,7 +3089,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
// can be followed by a unary op in a valid combination,
// due to how precedence works, unaries will always disappear first
- _set_error("Parser bug..");
+ _set_error("Parser bug...");
}
op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
@@ -3119,9 +3142,18 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
if (get_scalar_type(cn->datatype) == base) {
- for (int j = 0; j < cn->values.size(); j++) {
- values.push_back(cn->values[j]);
- }
+ int cardinality = get_cardinality(op->arguments[i]->get_datatype());
+ if (cn->values.size() == cardinality) {
+
+ for (int j = 0; j < cn->values.size(); j++) {
+ values.push_back(cn->values[j]);
+ }
+ } else if (cn->values.size() == 1) {
+
+ for (int j = 0; j < cardinality; j++) {
+ values.push_back(cn->values[0]);
+ }
+ } // else: should be filtered by the parser as it's an invalid constructor
} else if (get_scalar_type(cn->datatype) == cn->datatype) {
ConstantNode::Value v;
@@ -3215,7 +3247,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
precision = get_token_precision(tk.type);
tk = _get_token();
if (!is_token_nonvoid_datatype(tk.type)) {
- _set_error("Expected datatype after precission");
+ _set_error("Expected datatype after precision");
return ERR_PARSE_ERROR;
}
}
@@ -3513,7 +3545,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
if (!p_can_break) {
//all is good
- _set_error("Contiuning is not allowed here");
+ _set_error("Continuing is not allowed here");
}
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
@@ -3664,7 +3696,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_set_error("void datatype not allowed here");
return ERR_PARSE_ERROR;
}
- if (!uniform && type < TYPE_FLOAT && type > TYPE_VEC4) { // FIXME: always false! should it be || instead?
+
+ if (!uniform && (type < TYPE_FLOAT || type > TYPE_VEC4)) {
_set_error("Invalid type for varying, only float,vec2,vec3,vec4 allowed.");
return ERR_PARSE_ERROR;
}
@@ -3699,26 +3732,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
//todo parse default value
tk = _get_token();
- if (tk.type == TK_OP_ASSIGN) {
-
- Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
- if (!expr)
- return ERR_PARSE_ERROR;
- if (expr->type != Node::TYPE_CONSTANT) {
- _set_error("Expected constant expression after '='");
- return ERR_PARSE_ERROR;
- }
-
- ConstantNode *cn = static_cast<ConstantNode *>(expr);
-
- uniform.default_value.resize(cn->values.size());
-
- if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) {
- _set_error("Can't convert constant to " + get_datatype_name(uniform.type));
- return ERR_PARSE_ERROR;
- }
- tk = _get_token();
- }
if (tk.type == TK_COLON) {
//hint
@@ -3834,6 +3847,27 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
+ if (tk.type == TK_OP_ASSIGN) {
+
+ Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ if (!expr)
+ return ERR_PARSE_ERROR;
+ if (expr->type != Node::TYPE_CONSTANT) {
+ _set_error("Expected constant expression after '='");
+ return ERR_PARSE_ERROR;
+ }
+
+ ConstantNode *cn = static_cast<ConstantNode *>(expr);
+
+ uniform.default_value.resize(cn->values.size());
+
+ if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) {
+ _set_error("Can't convert constant to " + get_datatype_name(uniform.type));
+ return ERR_PARSE_ERROR;
+ }
+ tk = _get_token();
+ }
+
shader->uniforms[name] = uniform;
if (tk.type != TK_SEMICOLON) {
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index e8cdf1f897..720511e18d 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -425,6 +425,7 @@ public:
FunctionNode() {
type = TYPE_FUNCTION;
+ return_type = TYPE_VOID;
return_precision = PRECISION_DEFAULT;
can_discard = false;
}
@@ -532,6 +533,7 @@ public:
static bool convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value = NULL);
static DataType get_scalar_type(DataType p_type);
+ static int get_cardinality(DataType p_type);
static bool is_scalar_type(DataType p_type);
static bool is_sampler_type(DataType p_type);
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 9042649337..95193f7a8f 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -173,6 +173,8 @@ ShaderTypes::ShaderTypes() {
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.insert("shadows_disabled");
+
shader_modes[VS::SHADER_SPATIAL].modes.insert("vertex_lighting");
/************ CANVAS ITEM **************************/
@@ -207,7 +209,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].can_discard = true;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC2);
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["NORMAL"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["COLOR"] = constt(ShaderLanguage::TYPE_VEC4);
@@ -218,9 +220,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_SHADOW"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2);
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;
@@ -232,6 +233,7 @@ ShaderTypes::ShaderTypes() {
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.insert("unshaded");
shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("light_only");
@@ -254,7 +256,6 @@ 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("billboard");
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");
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 3e6e524117..6439ba8509 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -440,13 +440,17 @@ void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point
if (p_antialiased) {
pline->line_colors.push_back(Color(1, 1, 1, 1));
}
- }
- if (p_colors.size() == 1) {
+ } else if (p_colors.size() == 1) {
pline->triangle_colors = p_colors;
pline->line_colors = p_colors;
} else {
- pline->triangle_colors.resize(pline->triangles.size());
- pline->line_colors.resize(pline->lines.size());
+ if (p_colors.size() != p_points.size()) {
+ pline->triangle_colors.push_back(p_colors[0]);
+ pline->line_colors.push_back(p_colors[0]);
+ } else {
+ pline->triangle_colors.resize(pline->triangles.size());
+ pline->line_colors.resize(pline->lines.size());
+ }
}
for (int i = 0; i < p_points.size(); i++) {
@@ -690,7 +694,7 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
canvas_item->commands.push_back(polygon);
}
-void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, int p_count, RID p_normal_map) {
+void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -698,6 +702,8 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
int ps = p_points.size();
ERR_FAIL_COND(!p_colors.empty() && p_colors.size() != ps && p_colors.size() != 1);
ERR_FAIL_COND(!p_uvs.empty() && p_uvs.size() != ps);
+ ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != ps * 4);
+ ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != ps * 4);
Vector<int> indices = p_indices;
@@ -722,6 +728,8 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
polygon->points = p_points;
polygon->uvs = p_uvs;
polygon->colors = p_colors;
+ polygon->bones = p_bones;
+ polygon->weights = p_weights;
polygon->indices = indices;
polygon->count = count;
polygon->antialiased = false;
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index 6a5a7623b6..4d9398a17e 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -51,8 +51,6 @@ public:
Vector<Item *> child_items;
- RID skeleton;
-
Item() {
children_order_dirty = true;
E = NULL;
@@ -183,7 +181,7 @@ public:
void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID());
void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID());
void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false);
- void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
+ void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames);
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 64a3502e40..fca3126604 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -205,4 +205,5 @@ VisualServerRaster::~VisualServerRaster() {
memdelete(VSG::canvas);
memdelete(VSG::viewport);
memdelete(VSG::rasterizer);
+ memdelete(VSG::scene);
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index a94e110b5d..f7151e54f9 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
@@ -148,6 +150,7 @@ public:
BIND0R(RID, texture_create)
BIND5(texture_allocate, RID, int, int, Image::Format, uint32_t)
BIND3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
+ BIND10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, CubeMapSide)
BIND2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
BIND2(texture_set_flags, RID, uint32_t)
BIND1RC(uint32_t, texture_get_flags, RID)
@@ -285,6 +288,7 @@ public:
BIND2RC(Transform, skeleton_bone_get_transform, RID, int)
BIND3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
BIND2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
+ BIND2(skeleton_set_base_transform_2d, RID, const Transform2D &)
/* Light API */
@@ -450,6 +454,7 @@ public:
BIND2(viewport_set_hide_canvas, RID, bool)
BIND2(viewport_set_disable_environment, RID, bool)
BIND2(viewport_set_disable_3d, RID, bool)
+ BIND2(viewport_set_keep_3d_linear, RID, bool)
BIND2(viewport_attach_camera, RID, RID)
BIND2(viewport_set_scenario, RID, RID)
@@ -486,7 +491,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)
@@ -580,7 +585,7 @@ public:
BIND11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID)
BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
BIND7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
- BIND8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
+ BIND10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
BIND4(canvas_item_add_mesh, RID, const RID &, RID, RID)
BIND4(canvas_item_add_multimesh, RID, RID, RID, RID)
BIND6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 0920fa748b..697c890c9a 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -730,6 +730,11 @@ void VisualServerScene::instance_set_exterior(RID p_instance, bool p_enabled) {
}
void VisualServerScene::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) {
+ Instance *instance = instance_owner.get(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->extra_margin = p_margin;
+ _instance_queue_update(instance, true, false);
}
Vector<ObjectID> VisualServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const {
@@ -1252,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: {
@@ -1354,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();
@@ -1464,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++) {
@@ -1519,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++) {
@@ -1541,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;
@@ -1572,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);
@@ -1597,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;
}
@@ -1611,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];
@@ -1628,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;
@@ -1669,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) {
@@ -1679,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);
@@ -1688,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);
@@ -1708,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;
@@ -1726,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];
@@ -1852,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 {
@@ -1865,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
{
@@ -2002,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 */
@@ -2013,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) {
@@ -2088,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
@@ -3333,6 +3416,7 @@ VisualServerScene::~VisualServerScene() {
#ifndef NO_THREADS
probe_bake_thread_exit = true;
+ probe_bake_sem->post();
Thread::wait_to_finish(probe_bake_thread);
memdelete(probe_bake_thread);
memdelete(probe_bake_sem);
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 3eb8953c1f..dcc270ca5e 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -178,11 +178,14 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
VSG::rasterizer->restore_render_target();
if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) {
+ Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
- if (can_draw_3d) {
- VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
- } else {
+ if (!can_draw_3d) {
VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ } else if (p_viewport->use_arvr && arvr_interface.is_valid()) {
+ VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
scenario_draw_canvas_bg = false;
}
@@ -210,11 +213,14 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
i++;
if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) {
+ Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
- if (can_draw_3d) {
- VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
- } else {
+ if (!can_draw_3d) {
VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ } else if (p_viewport->use_arvr && arvr_interface.is_valid()) {
+ VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
scenario_draw_canvas_bg = false;
@@ -222,11 +228,14 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
}
if (scenario_draw_canvas_bg) {
+ Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
- if (can_draw_3d) {
- VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
- } else {
+ if (!can_draw_3d) {
VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ } else if (p_viewport->use_arvr && arvr_interface.is_valid()) {
+ VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
scenario_draw_canvas_bg = false;
@@ -239,10 +248,9 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
void VisualServerViewport::draw_viewports() {
// get our arvr interface in case we need it
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
- if (arvr_interface.is_valid()) {
- // update our positioning information as late as possible...
- arvr_interface->process();
- }
+
+ // process all our active interfaces
+ ARVRServer::get_singleton()->_process();
clear_color = GLOBAL_GET("rendering/environment/default_clear_color");
@@ -286,6 +294,9 @@ void VisualServerViewport::draw_viewports() {
_draw_viewport(vp, ARVRInterface::EYE_RIGHT);
arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect);
}
+
+ // and for our frame timing, mark when we've finished commiting our eyes
+ ARVRServer::get_singleton()->_mark_commit();
} else {
VSG::rasterizer->set_current_render_target(vp->render_target);
@@ -451,6 +462,15 @@ void VisualServerViewport::viewport_set_disable_3d(RID p_viewport, bool p_disabl
//this should be just for disabling rendering of 3D, to actually disable it, set usage
}
+void VisualServerViewport::viewport_set_keep_3d_linear(RID p_viewport, bool p_keep_3d_linear) {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->keep_3d_linear = p_keep_3d_linear;
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR, p_keep_3d_linear);
+}
+
void VisualServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index 1d28cf22a3..c0c83c0450 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -64,6 +64,7 @@ public:
bool disable_environment;
bool disable_3d;
bool disable_3d_by_usage;
+ bool keep_3d_linear;
RID shadow_atlas;
int shadow_atlas_size;
@@ -110,6 +111,7 @@ public:
shadow_atlas_size = 0;
disable_3d = false;
disable_3d_by_usage = false;
+ keep_3d_linear = false;
debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
for (int i = 0; i < VS::VIEWPORT_RENDER_INFO_MAX; i++) {
render_info[i] = 0;
@@ -164,6 +166,7 @@ public:
void viewport_set_hide_canvas(RID p_viewport, bool p_hide);
void viewport_set_disable_environment(RID p_viewport, bool p_disable);
void viewport_set_disable_3d(RID p_viewport, bool p_disable);
+ void viewport_set_keep_3d_linear(RID p_viewport, bool p_keep_3d_linear);
void viewport_attach_camera(RID p_viewport, RID p_camera);
void viewport_set_scenario(RID p_viewport, RID p_scenario);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index b91f80d137..8b5a334341 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -84,6 +84,7 @@ public:
FUNCRID(texture)
FUNC5(texture_allocate, RID, int, int, Image::Format, uint32_t)
FUNC3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
+ FUNC10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, CubeMapSide)
FUNC2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
FUNC2(texture_set_flags, RID, uint32_t)
FUNC1RC(uint32_t, texture_get_flags, RID)
@@ -221,6 +222,7 @@ public:
FUNC2RC(Transform, skeleton_bone_get_transform, RID, int)
FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
+ FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &)
/* Light API */
@@ -377,6 +379,7 @@ public:
FUNC2(viewport_set_hide_canvas, RID, bool)
FUNC2(viewport_set_disable_environment, RID, bool)
FUNC2(viewport_set_disable_3d, RID, bool)
+ FUNC2(viewport_set_keep_3d_linear, RID, bool)
FUNC2(viewport_attach_camera, RID, RID)
FUNC2(viewport_set_scenario, RID, RID)
@@ -413,7 +416,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)
@@ -498,7 +501,7 @@ public:
FUNC11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID)
FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
FUNC7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
- FUNC8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
+ FUNC10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
FUNC4(canvas_item_add_mesh, RID, const RID &, RID, RID)
FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID)
FUNC6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 47577a3359..21745e87a8 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -214,9 +214,9 @@ RID VisualServer::_make_test_cube() {
for (int k = 0; k < 3; k++) {
if (i < 3)
- face_points[j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
+ face_points[j][(i + k) % 3] = v[k];
else
- face_points[3 - j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
+ face_points[3 - j][(i + k) % 3] = -v[k];
}
normal_points[j] = Vector3();
normal_points[j][i % 3] = (i >= 3 ? -1 : 1);
@@ -1528,6 +1528,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_create_from_image", "image", "flags"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
ClassDB::bind_method(D_METHOD("texture_allocate", "texture", "width", "height", "format", "flags"), &VisualServer::texture_allocate, DEFVAL(TEXTURE_FLAGS_DEFAULT));
ClassDB::bind_method(D_METHOD("texture_set_data", "texture", "image", "cube_side"), &VisualServer::texture_set_data, DEFVAL(CUBEMAP_LEFT));
+ ClassDB::bind_method(D_METHOD("texture_set_data_partial", "texture", "image", "src_x", "src_y", "src_w", "src_h", "dst_x", "dst_y", "dst_mip", "cube_side"), &VisualServer::texture_set_data_partial, DEFVAL(CUBEMAP_LEFT));
ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "cube_side"), &VisualServer::texture_get_data, DEFVAL(CUBEMAP_LEFT));
ClassDB::bind_method(D_METHOD("texture_set_flags", "texture", "flags"), &VisualServer::texture_set_flags);
ClassDB::bind_method(D_METHOD("texture_get_flags", "texture"), &VisualServer::texture_get_flags);
@@ -1827,9 +1828,9 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_add_nine_patch", "item", "rect", "source", "texture", "topleft", "bottomright", "x_axis_mode", "y_axis_mode", "draw_center", "modulate", "normal_map"), &VisualServer::canvas_item_add_nine_patch, DEFVAL(NINE_PATCH_STRETCH), DEFVAL(NINE_PATCH_STRETCH), DEFVAL(true), DEFVAL(Color(1, 1, 1)), DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("canvas_item_add_primitive", "item", "points", "colors", "uvs", "texture", "width", "normal_map"), &VisualServer::canvas_item_add_primitive, DEFVAL(1.0), DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("canvas_item_add_polygon", "item", "points", "colors", "uvs", "texture", "normal_map", "antialiased"), &VisualServer::canvas_item_add_polygon, DEFVAL(Vector<Point2>()), DEFVAL(RID()), DEFVAL(RID()), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("canvas_item_add_triangle_array", "item", "indices", "points", "colors", "uvs", "texture", "count", "normal_map"), &VisualServer::canvas_item_add_triangle_array, DEFVAL(Vector<Point2>()), DEFVAL(RID()), DEFVAL(-1), DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("canvas_item_add_mesh", "item", "mesh", "skeleton"), &VisualServer::canvas_item_add_mesh, DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("canvas_item_add_multimesh", "item", "mesh", "skeleton"), &VisualServer::canvas_item_add_multimesh, DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_triangle_array", "item", "indices", "points", "colors", "uvs", "bones", "weights", "texture", "count", "normal_map"), &VisualServer::canvas_item_add_triangle_array, DEFVAL(Vector<Point2>()), DEFVAL(Vector<int>()), DEFVAL(Vector<float>()), DEFVAL(RID()), DEFVAL(-1), DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_mesh", "item", "mesh", "texture", "normal_map"), &VisualServer::canvas_item_add_mesh, DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_multimesh", "item", "mesh", "texture", "normal_map"), &VisualServer::canvas_item_add_multimesh, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture", "normal_map", "h_frames", "v_frames"), &VisualServer::canvas_item_add_particles);
ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &VisualServer::canvas_item_add_set_transform);
ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &VisualServer::canvas_item_add_clip_ignore);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 537588fd6f..73d96d60f7 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -109,6 +109,7 @@ public:
RID texture_create_from_image(const Ref<Image> &p_image, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT); // helper
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT) = 0;
virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
+ virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
virtual Ref<Image> texture_get_data(RID p_texture, CubeMapSide p_cube_side = CUBEMAP_LEFT) const = 0;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
@@ -232,7 +233,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
};
@@ -351,6 +352,7 @@ public:
virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
+ virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
/* Light API */
@@ -591,6 +593,7 @@ public:
virtual void viewport_set_hide_canvas(RID p_viewport, bool p_hide) = 0;
virtual void viewport_set_disable_environment(RID p_viewport, bool p_disable) = 0;
virtual void viewport_set_disable_3d(RID p_viewport, bool p_disable) = 0;
+ virtual void viewport_set_keep_3d_linear(RID p_viewport, bool p_disable) = 0;
virtual void viewport_attach_camera(RID p_viewport, RID p_camera) = 0;
virtual void viewport_set_scenario(RID p_viewport, RID p_scenario) = 0;
@@ -716,7 +719,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;
@@ -845,7 +848,7 @@ public:
virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false) = 0;
- virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, int p_h_frames, int p_v_frames) = 0;