summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/SCsub2
-rw-r--r--scene/resources/animation.cpp787
-rw-r--r--scene/resources/animation.h41
-rw-r--r--scene/resources/audio_stream_sample.cpp173
-rw-r--r--scene/resources/audio_stream_sample.h26
-rw-r--r--scene/resources/bit_map.cpp91
-rw-r--r--scene/resources/bit_map.h3
-rw-r--r--scene/resources/box_shape_3d.cpp (renamed from scene/resources/box_shape.cpp)36
-rw-r--r--scene/resources/box_shape_3d.h (renamed from scene/resources/box_shape.h)16
-rw-r--r--scene/resources/camera_effects.cpp197
-rw-r--r--scene/resources/camera_effects.h (renamed from scene/resources/space_2d.h)66
-rw-r--r--scene/resources/canvas.cpp46
-rw-r--r--scene/resources/canvas.h48
-rw-r--r--scene/resources/capsule_shape_2d.cpp39
-rw-r--r--scene/resources/capsule_shape_2d.h7
-rw-r--r--scene/resources/capsule_shape_3d.cpp (renamed from scene/resources/capsule_shape.cpp)74
-rw-r--r--scene/resources/capsule_shape_3d.h (renamed from scene/resources/capsule_shape.h)16
-rw-r--r--scene/resources/circle_shape_2d.cpp24
-rw-r--r--scene/resources/circle_shape_2d.h7
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp68
-rw-r--r--scene/resources/concave_polygon_shape_2d.h11
-rw-r--r--scene/resources/concave_polygon_shape_3d.cpp (renamed from scene/resources/concave_polygon_shape.cpp)52
-rw-r--r--scene/resources/concave_polygon_shape_3d.h (renamed from scene/resources/concave_polygon_shape.h)30
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp41
-rw-r--r--scene/resources/convex_polygon_shape_2d.h7
-rw-r--r--scene/resources/convex_polygon_shape_3d.cpp (renamed from scene/resources/convex_polygon_shape.cpp)46
-rw-r--r--scene/resources/convex_polygon_shape_3d.h (renamed from scene/resources/convex_polygon_shape.h)22
-rw-r--r--scene/resources/curve.cpp392
-rw-r--r--scene/resources/curve.h27
-rw-r--r--scene/resources/cylinder_shape_3d.cpp (renamed from scene/resources/cylinder_shape.cpp)52
-rw-r--r--scene/resources/cylinder_shape_3d.h (renamed from scene/resources/cylinder_shape.h)20
-rw-r--r--scene/resources/default_theme/SCsub2
-rw-r--r--scene/resources/default_theme/bookmark.pngbin0 -> 160 bytes
-rw-r--r--scene/resources/default_theme/default_theme.cpp227
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/default_theme/icon_file.pngbin0 -> 183 bytes
-rwxr-xr-xscene/resources/default_theme/make_header.py18
-rw-r--r--scene/resources/default_theme/theme_data.h8
-rw-r--r--scene/resources/dynamic_font.cpp387
-rw-r--r--scene/resources/dynamic_font.h63
-rw-r--r--scene/resources/environment.cpp1682
-rw-r--r--scene/resources/environment.h523
-rw-r--r--scene/resources/font.cpp242
-rw-r--r--scene/resources/font.h58
-rw-r--r--scene/resources/gradient.cpp29
-rw-r--r--scene/resources/gradient.h31
-rw-r--r--scene/resources/height_map_shape_3d.cpp (renamed from scene/resources/height_map_shape.cpp)69
-rw-r--r--scene/resources/height_map_shape_3d.h (renamed from scene/resources/height_map_shape.h)21
-rw-r--r--scene/resources/line_shape_2d.cpp58
-rw-r--r--scene/resources/line_shape_2d.h13
-rw-r--r--scene/resources/material.cpp1773
-rw-r--r--scene/resources/material.h272
-rw-r--r--scene/resources/mesh.cpp999
-rw-r--r--scene/resources/mesh.h122
-rw-r--r--scene/resources/mesh_data_tool.cpp237
-rw-r--r--scene/resources/mesh_data_tool.h3
-rw-r--r--scene/resources/mesh_library.cpp86
-rw-r--r--scene/resources/mesh_library.h19
-rw-r--r--scene/resources/multimesh.cpp257
-rw-r--r--scene/resources/multimesh.h58
-rw-r--r--scene/resources/navigation_mesh.cpp536
-rw-r--r--scene/resources/navigation_mesh.h193
-rw-r--r--scene/resources/packed_scene.cpp344
-rw-r--r--scene/resources/packed_scene.h13
-rw-r--r--scene/resources/particles_material.cpp707
-rw-r--r--scene/resources/particles_material.h104
-rw-r--r--scene/resources/physics_material.cpp11
-rw-r--r--scene/resources/physics_material.h19
-rw-r--r--scene/resources/polygon_path_finder.cpp121
-rw-r--r--scene/resources/polygon_path_finder.h9
-rw-r--r--scene/resources/primitive_meshes.cpp277
-rw-r--r--scene/resources/primitive_meshes.h54
-rw-r--r--scene/resources/ray_shape_2d.cpp105
-rw-r--r--scene/resources/ray_shape_2d.h61
-rw-r--r--scene/resources/ray_shape_3d.cpp (renamed from scene/resources/ray_shape.cpp)47
-rw-r--r--scene/resources/ray_shape_3d.h (renamed from scene/resources/ray_shape.h)16
-rw-r--r--scene/resources/rectangle_shape_2d.cpp21
-rw-r--r--scene/resources/rectangle_shape_2d.h5
-rw-r--r--scene/resources/resource_format_text.cpp476
-rw-r--r--scene/resources/resource_format_text.h35
-rw-r--r--scene/resources/segment_shape_2d.cpp105
-rw-r--r--scene/resources/segment_shape_2d.h31
-rw-r--r--scene/resources/shader.cpp76
-rw-r--r--scene/resources/shader.h22
-rw-r--r--scene/resources/shape_2d.cpp28
-rw-r--r--scene/resources/shape_2d.h4
-rw-r--r--scene/resources/shape_3d.cpp (renamed from scene/resources/shape.cpp)58
-rw-r--r--scene/resources/shape_3d.h (renamed from scene/resources/shape.h)30
-rw-r--r--scene/resources/skin.cpp32
-rw-r--r--scene/resources/skin.h12
-rw-r--r--scene/resources/sky.cpp566
-rw-r--r--scene/resources/sky.h152
-rw-r--r--scene/resources/sky_material.cpp595
-rw-r--r--scene/resources/sky_material.h189
-rw-r--r--scene/resources/space_2d.cpp66
-rw-r--r--scene/resources/sphere_shape_3d.cpp (renamed from scene/resources/sphere_shape.cpp)39
-rw-r--r--scene/resources/sphere_shape_3d.h (renamed from scene/resources/sphere_shape.h)20
-rw-r--r--scene/resources/style_box.cpp172
-rw-r--r--scene/resources/style_box.h45
-rw-r--r--scene/resources/surface_tool.cpp346
-rw-r--r--scene/resources/surface_tool.h2
-rw-r--r--scene/resources/syntax_highlighter.cpp636
-rw-r--r--scene/resources/syntax_highlighter.h140
-rw-r--r--scene/resources/text_file.cpp9
-rw-r--r--scene/resources/text_file.h3
-rw-r--r--scene/resources/texture.cpp2321
-rw-r--r--scene/resources/texture.h713
-rw-r--r--scene/resources/theme.cpp306
-rw-r--r--scene/resources/theme.h37
-rw-r--r--scene/resources/tile_set.cpp344
-rw-r--r--scene/resources/tile_set.h66
-rw-r--r--scene/resources/video_stream.h5
-rw-r--r--scene/resources/visual_shader.cpp957
-rw-r--r--scene/resources/visual_shader.h231
-rw-r--r--scene/resources/visual_shader_nodes.cpp1889
-rw-r--r--scene/resources/visual_shader_nodes.h1487
-rw-r--r--scene/resources/world_2d.cpp108
-rw-r--r--scene/resources/world_2d.h5
-rw-r--r--scene/resources/world_3d.cpp (renamed from scene/resources/world.cpp)213
-rw-r--r--scene/resources/world_3d.h (renamed from scene/resources/world.h)50
-rw-r--r--scene/resources/world_margin_shape_3d.cpp (renamed from scene/resources/plane_shape.cpp)34
-rw-r--r--scene/resources/world_margin_shape_3d.h (renamed from scene/resources/plane_shape.h)25
122 files changed, 14583 insertions, 10466 deletions
diff --git a/scene/resources/SCsub b/scene/resources/SCsub
index 5e5b6f8fd5..3a86b22835 100644
--- a/scene/resources/SCsub
+++ b/scene/resources/SCsub
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-Import('env')
+Import("env")
env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 91d1e32053..b8edd70712 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -31,43 +31,33 @@
#include "animation.h"
#include "scene/scene_string_names.h"
-#include "core/math/geometry.h"
+#include "core/math/geometry_3d.h"
#define ANIM_MIN_LENGTH 0.001
bool Animation::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("tracks/")) {
-
int track = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
if (tracks.size() == track && what == "type") {
-
String type = p_value;
if (type == "transform") {
-
add_track(TYPE_TRANSFORM);
} else if (type == "value") {
-
add_track(TYPE_VALUE);
} else if (type == "method") {
-
add_track(TYPE_METHOD);
} else if (type == "bezier") {
-
add_track(TYPE_BEZIER);
} else if (type == "audio") {
-
add_track(TYPE_AUDIO);
} else if (type == "animation") {
-
add_track(TYPE_ANIMATION);
} else {
-
return false;
}
@@ -76,31 +66,28 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_INDEX_V(track, tracks.size(), false);
- if (what == "path")
+ if (what == "path") {
track_set_path(track, p_value);
- else if (what == "interp")
+ } else if (what == "interp") {
track_set_interpolation_type(track, InterpolationType(p_value.operator int()));
- else if (what == "loop_wrap")
+ } else if (what == "loop_wrap") {
track_set_interpolation_loop_wrap(track, p_value);
- else if (what == "imported")
+ } else if (what == "imported") {
track_set_imported(track, p_value);
- else if (what == "enabled")
+ } else if (what == "enabled") {
track_set_enabled(track, p_value);
- else if (what == "keys" || what == "key_values") {
-
+ } else if (what == "keys" || what == "key_values") {
if (track_get_type(track) == TYPE_TRANSFORM) {
-
TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]);
- PoolVector<float> values = p_value;
+ Vector<float> values = p_value;
int vcount = values.size();
ERR_FAIL_COND_V(vcount % 12, false); // should be multiple of 11
- PoolVector<float>::Read r = values.read();
+ const float *r = values.ptr();
tt->transforms.resize(vcount / 12);
for (int i = 0; i < (vcount / 12); i++) {
-
TKey<TransformKey> &tk = tt->transforms.write[i];
const float *ofs = &r[i * 12];
tk.time = ofs[0];
@@ -121,7 +108,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
}
} else if (track_get_type(track) == TYPE_VALUE) {
-
ValueTrack *vt = static_cast<ValueTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
@@ -133,41 +119,38 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
if (d.has("update")) {
int um = d["update"];
- if (um < 0)
+ if (um < 0) {
um = 0;
- else if (um > 3)
+ } else if (um > 3) {
um = 3;
+ }
vt->update_mode = UpdateMode(um);
}
- PoolVector<float> times = d["times"];
+ Vector<float> times = d["times"];
Array values = d["values"];
ERR_FAIL_COND_V(times.size() != values.size(), false);
if (times.size()) {
-
int valcount = times.size();
- PoolVector<float>::Read rt = times.read();
+ const float *rt = times.ptr();
vt->values.resize(valcount);
for (int i = 0; i < valcount; i++) {
-
vt->values.write[i].time = rt[i];
vt->values.write[i].value = values[i];
}
if (d.has("transitions")) {
-
- PoolVector<float> transitions = d["transitions"];
+ Vector<float> transitions = d["transitions"];
ERR_FAIL_COND_V(transitions.size() != valcount, false);
- PoolVector<float>::Read rtr = transitions.read();
+ const float *rtr = transitions.ptr();
for (int i = 0; i < valcount; i++) {
-
vt->values.write[i].transition = rtr[i];
}
}
@@ -176,66 +159,59 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
return true;
} else if (track_get_type(track) == TYPE_METHOD) {
-
- while (track_get_key_count(track))
+ while (track_get_key_count(track)) {
track_remove_key(track, 0); //well shouldn't be set anyway
+ }
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
ERR_FAIL_COND_V(!d.has("values"), false);
- PoolVector<float> times = d["times"];
+ Vector<float> times = d["times"];
Array values = d["values"];
ERR_FAIL_COND_V(times.size() != values.size(), false);
if (times.size()) {
-
int valcount = times.size();
- PoolVector<float>::Read rt = times.read();
+ const float *rt = times.ptr();
for (int i = 0; i < valcount; i++) {
-
track_insert_key(track, rt[i], values[i]);
}
if (d.has("transitions")) {
-
- PoolVector<float> transitions = d["transitions"];
+ Vector<float> transitions = d["transitions"];
ERR_FAIL_COND_V(transitions.size() != valcount, false);
- PoolVector<float>::Read rtr = transitions.read();
+ const float *rtr = transitions.ptr();
for (int i = 0; i < valcount; i++) {
-
track_set_key_transition(track, i, rtr[i]);
}
}
}
} else if (track_get_type(track) == TYPE_BEZIER) {
-
BezierTrack *bt = static_cast<BezierTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
ERR_FAIL_COND_V(!d.has("points"), false);
- PoolVector<float> times = d["times"];
- PoolRealArray values = d["points"];
+ Vector<float> times = d["times"];
+ PackedFloat32Array values = d["points"];
ERR_FAIL_COND_V(times.size() * 5 != values.size(), false);
if (times.size()) {
-
int valcount = times.size();
- PoolVector<float>::Read rt = times.read();
- PoolVector<float>::Read rv = values.read();
+ const float *rt = times.ptr();
+ const float *rv = values.ptr();
bt->values.resize(valcount);
for (int i = 0; i < valcount; i++) {
-
bt->values.write[i].time = rt[i];
bt->values.write[i].transition = 0; //unused in bezier
bt->values.write[i].value.value = rv[i * 5 + 0];
@@ -248,34 +224,34 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
return true;
} else if (track_get_type(track) == TYPE_AUDIO) {
-
AudioTrack *ad = static_cast<AudioTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
ERR_FAIL_COND_V(!d.has("clips"), false);
- PoolVector<float> times = d["times"];
+ Vector<float> times = d["times"];
Array clips = d["clips"];
ERR_FAIL_COND_V(clips.size() != times.size(), false);
if (times.size()) {
-
int valcount = times.size();
- PoolVector<float>::Read rt = times.read();
+ const float *rt = times.ptr();
ad->values.clear();
for (int i = 0; i < valcount; i++) {
-
Dictionary d2 = clips[i];
- if (!d2.has("start_offset"))
+ if (!d2.has("start_offset")) {
continue;
- if (!d2.has("end_offset"))
+ }
+ if (!d2.has("end_offset")) {
continue;
- if (!d2.has("stream"))
+ }
+ if (!d2.has("stream")) {
continue;
+ }
TKey<AudioKey> ak;
ak.time = rt[i];
@@ -289,28 +265,25 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
return true;
} else if (track_get_type(track) == TYPE_ANIMATION) {
-
AnimationTrack *an = static_cast<AnimationTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
ERR_FAIL_COND_V(!d.has("clips"), false);
- PoolVector<float> times = d["times"];
- PoolVector<String> clips = d["clips"];
+ Vector<float> times = d["times"];
+ Vector<String> clips = d["clips"];
ERR_FAIL_COND_V(clips.size() != times.size(), false);
if (times.size()) {
-
int valcount = times.size();
- PoolVector<float>::Read rt = times.read();
- PoolVector<String>::Read rc = clips.read();
+ const float *rt = times.ptr();
+ const String *rc = clips.ptr();
an->values.resize(valcount);
for (int i = 0; i < valcount; i++) {
-
TKey<StringName> ak;
ak.time = rt[i];
ak.value = rc[i];
@@ -322,66 +295,73 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
} else {
return false;
}
- } else
+ } else {
return false;
- } else
+ }
+ } else {
return false;
+ }
return true;
}
bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
- if (name == "length")
+ if (name == "length") {
r_ret = length;
- else if (name == "loop")
+ } else if (name == "loop") {
r_ret = loop;
- else if (name == "step")
+ } else if (name == "step") {
r_ret = step;
- else if (name.begins_with("tracks/")) {
-
+ } else if (name.begins_with("tracks/")) {
int track = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
ERR_FAIL_INDEX_V(track, tracks.size(), false);
if (what == "type") {
-
switch (track_get_type(track)) {
-
- case TYPE_TRANSFORM: r_ret = "transform"; break;
- case TYPE_VALUE: r_ret = "value"; break;
- case TYPE_METHOD: r_ret = "method"; break;
- case TYPE_BEZIER: r_ret = "bezier"; break;
- case TYPE_AUDIO: r_ret = "audio"; break;
- case TYPE_ANIMATION: r_ret = "animation"; break;
+ case TYPE_TRANSFORM:
+ r_ret = "transform";
+ break;
+ case TYPE_VALUE:
+ r_ret = "value";
+ break;
+ case TYPE_METHOD:
+ r_ret = "method";
+ break;
+ case TYPE_BEZIER:
+ r_ret = "bezier";
+ break;
+ case TYPE_AUDIO:
+ r_ret = "audio";
+ break;
+ case TYPE_ANIMATION:
+ r_ret = "animation";
+ break;
}
return true;
- } else if (what == "path")
+ } else if (what == "path") {
r_ret = track_get_path(track);
- else if (what == "interp")
+ } else if (what == "interp") {
r_ret = track_get_interpolation_type(track);
- else if (what == "loop_wrap")
+ } else if (what == "loop_wrap") {
r_ret = track_get_interpolation_loop_wrap(track);
- else if (what == "imported")
+ } else if (what == "imported") {
r_ret = track_is_imported(track);
- else if (what == "enabled")
+ } else if (what == "enabled") {
r_ret = track_is_enabled(track);
- else if (what == "keys") {
-
+ } else if (what == "keys") {
if (track_get_type(track) == TYPE_TRANSFORM) {
-
- PoolVector<real_t> keys;
+ Vector<float> keys;
int kk = track_get_key_count(track);
keys.resize(kk * 12);
- PoolVector<real_t>::Write w = keys.write();
+ real_t *w = keys.ptrw();
int idx = 0;
for (int i = 0; i < track_get_key_count(track); i++) {
-
Vector3 loc;
Quat rot;
Vector3 scale;
@@ -403,18 +383,16 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
w[idx++] = scale.z;
}
- w.release();
r_ret = keys;
return true;
} else if (track_get_type(track) == TYPE_VALUE) {
-
const ValueTrack *vt = static_cast<const ValueTrack *>(tracks[track]);
Dictionary d;
- PoolVector<float> key_times;
- PoolVector<float> key_transitions;
+ Vector<float> key_times;
+ Vector<float> key_transitions;
Array key_values;
int kk = vt->values.size();
@@ -423,24 +401,20 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
key_transitions.resize(kk);
key_values.resize(kk);
- PoolVector<float>::Write wti = key_times.write();
- PoolVector<float>::Write wtr = key_transitions.write();
+ float *wti = key_times.ptrw();
+ float *wtr = key_transitions.ptrw();
int idx = 0;
const TKey<Variant> *vls = vt->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[idx] = vls[i].time;
wtr[idx] = vls[i].transition;
key_values[idx] = vls[i].value;
idx++;
}
- wti.release();
- wtr.release();
-
d["times"] = key_times;
d["transitions"] = key_transitions;
d["values"] = key_values;
@@ -453,11 +427,10 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_METHOD) {
-
Dictionary d;
- PoolVector<float> key_times;
- PoolVector<float> key_transitions;
+ Vector<float> key_times;
+ Vector<float> key_transitions;
Array key_values;
int kk = track_get_key_count(track);
@@ -466,21 +439,17 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
key_transitions.resize(kk);
key_values.resize(kk);
- PoolVector<float>::Write wti = key_times.write();
- PoolVector<float>::Write wtr = key_transitions.write();
+ float *wti = key_times.ptrw();
+ float *wtr = key_transitions.ptrw();
int idx = 0;
for (int i = 0; i < track_get_key_count(track); i++) {
-
wti[idx] = track_get_key_time(track, i);
wtr[idx] = track_get_key_transition(track, i);
key_values[idx] = track_get_key_value(track, i);
idx++;
}
- wti.release();
- wtr.release();
-
d["times"] = key_times;
d["transitions"] = key_transitions;
d["values"] = key_values;
@@ -492,28 +461,26 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_BEZIER) {
-
const BezierTrack *bt = static_cast<const BezierTrack *>(tracks[track]);
Dictionary d;
- PoolVector<float> key_times;
- PoolVector<float> key_points;
+ Vector<float> key_times;
+ Vector<float> key_points;
int kk = bt->values.size();
key_times.resize(kk);
key_points.resize(kk * 5);
- PoolVector<float>::Write wti = key_times.write();
- PoolVector<float>::Write wpo = key_points.write();
+ float *wti = key_times.ptrw();
+ float *wpo = key_points.ptrw();
int idx = 0;
const TKey<BezierKey> *vls = bt->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[idx] = vls[i].time;
wpo[idx * 5 + 0] = vls[i].value.value;
wpo[idx * 5 + 1] = vls[i].value.in_handle.x;
@@ -523,9 +490,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
idx++;
}
- wti.release();
- wpo.release();
-
d["times"] = key_times;
d["points"] = key_points;
@@ -533,26 +497,24 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_AUDIO) {
-
const AudioTrack *ad = static_cast<const AudioTrack *>(tracks[track]);
Dictionary d;
- PoolVector<float> key_times;
+ Vector<float> key_times;
Array clips;
int kk = ad->values.size();
key_times.resize(kk);
- PoolVector<float>::Write wti = key_times.write();
+ float *wti = key_times.ptrw();
int idx = 0;
const TKey<AudioKey> *vls = ad->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[idx] = vls[i].time;
Dictionary clip;
clip["start_offset"] = vls[i].value.start_offset;
@@ -562,8 +524,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
idx++;
}
- wti.release();
-
d["times"] = key_times;
d["clips"] = clips;
@@ -571,33 +531,28 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_ANIMATION) {
-
const AnimationTrack *an = static_cast<const AnimationTrack *>(tracks[track]);
Dictionary d;
- PoolVector<float> key_times;
- PoolVector<String> clips;
+ Vector<float> key_times;
+ Vector<String> clips;
int kk = an->values.size();
key_times.resize(kk);
clips.resize(kk);
- PoolVector<float>::Write wti = key_times.write();
- PoolVector<String>::Write wcl = clips.write();
+ float *wti = key_times.ptrw();
+ String *wcl = clips.ptrw();
const TKey<StringName> *vls = an->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[i] = vls[i].time;
wcl[i] = vls[i].value;
}
- wti.release();
- wcl.release();
-
d["times"] = key_times;
d["clips"] = clips;
@@ -605,17 +560,18 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
}
- } else
+ } else {
return false;
- } else
+ }
+ } else {
return false;
+ }
return true;
}
void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < tracks.size(); i++) {
-
p_list->push_back(PropertyInfo(Variant::STRING, "tracks/" + itos(i) + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::NODE_PATH, "tracks/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -627,44 +583,36 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
}
int Animation::add_track(TrackType p_type, int p_at_pos) {
-
- if (p_at_pos < 0 || p_at_pos >= tracks.size())
+ if (p_at_pos < 0 || p_at_pos >= tracks.size()) {
p_at_pos = tracks.size();
+ }
switch (p_type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = memnew(TransformTrack);
tracks.insert(p_at_pos, tt);
} break;
case TYPE_VALUE: {
-
tracks.insert(p_at_pos, memnew(ValueTrack));
} break;
case TYPE_METHOD: {
-
tracks.insert(p_at_pos, memnew(MethodTrack));
} break;
case TYPE_BEZIER: {
-
tracks.insert(p_at_pos, memnew(BezierTrack));
} break;
case TYPE_AUDIO: {
-
tracks.insert(p_at_pos, memnew(AudioTrack));
} break;
case TYPE_ANIMATION: {
-
tracks.insert(p_at_pos, memnew(AnimationTrack));
} break;
default: {
-
ERR_PRINT("Unknown track type");
}
}
@@ -674,44 +622,36 @@ int Animation::add_track(TrackType p_type, int p_at_pos) {
}
void Animation::remove_track(int p_track) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
_clear(tt->transforms);
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
_clear(vt->values);
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
_clear(mt->methods);
} break;
case TYPE_BEZIER: {
-
BezierTrack *bz = static_cast<BezierTrack *>(t);
_clear(bz->values);
} break;
case TYPE_AUDIO: {
-
AudioTrack *ad = static_cast<AudioTrack *>(t);
_clear(ad->values);
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *an = static_cast<AnimationTrack *>(t);
_clear(an->values);
@@ -725,18 +665,15 @@ void Animation::remove_track(int p_track) {
}
int Animation::get_track_count() const {
-
return tracks.size();
}
Animation::TrackType Animation::track_get_type(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), TYPE_TRANSFORM);
return tracks[p_track]->type;
}
void Animation::track_set_path(int p_track, const NodePath &p_path) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
tracks[p_track]->path = p_path;
emit_changed();
@@ -744,23 +681,20 @@ void Animation::track_set_path(int p_track, const NodePath &p_path) {
}
NodePath Animation::track_get_path(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), NodePath());
return tracks[p_track]->path;
}
int Animation::find_track(const NodePath &p_path) const {
-
for (int i = 0; i < tracks.size(); i++) {
-
- if (tracks[i]->path == p_path)
+ if (tracks[i]->path == p_path) {
return i;
+ }
};
return -1;
};
void Animation::track_set_interpolation_type(int p_track, InterpolationType p_interp) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
ERR_FAIL_INDEX(p_interp, 3);
tracks[p_track]->interpolation = p_interp;
@@ -768,7 +702,6 @@ void Animation::track_set_interpolation_type(int p_track, InterpolationType p_in
}
Animation::InterpolationType Animation::track_get_interpolation_type(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
return tracks[p_track]->interpolation;
}
@@ -780,7 +713,6 @@ void Animation::track_set_interpolation_loop_wrap(int p_track, bool p_enable) {
}
bool Animation::track_get_interpolation_loop_wrap(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
return tracks[p_track]->loop_wrap;
}
@@ -811,23 +743,22 @@ int Animation::_insert_pos(float p_time, T& p_keys) {
}
}
+
*/
template <class T, class V>
int Animation::_insert(float p_time, T &p_keys, const V &p_value) {
-
int idx = p_keys.size();
while (true) {
-
// Condition for replacement.
if (idx > 0 && Math::is_equal_approx(p_keys[idx - 1].time, p_time)) {
-
+ float transition = p_keys[idx - 1].transition;
p_keys.write[idx - 1] = p_value;
+ p_keys.write[idx - 1].transition = transition;
return idx - 1;
// Condition for insert.
} else if (idx == 0 || p_keys[idx - 1].time < p_time) {
-
p_keys.insert(idx, p_value);
return idx;
}
@@ -840,12 +771,10 @@ int Animation::_insert(float p_time, T &p_keys, const V &p_value) {
template <class T>
void Animation::_clear(T &p_keys) {
-
p_keys.clear();
}
Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
Track *t = tracks[p_track];
@@ -853,18 +782,20 @@ Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc,
ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER);
ERR_FAIL_INDEX_V(p_key, tt->transforms.size(), ERR_INVALID_PARAMETER);
- if (r_loc)
+ if (r_loc) {
*r_loc = tt->transforms[p_key].value.loc;
- if (r_rot)
+ }
+ if (r_rot) {
*r_rot = tt->transforms[p_key].value.rot;
- if (r_scale)
+ }
+ if (r_scale) {
*r_scale = tt->transforms[p_key].value.scale;
+ }
return OK;
}
int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quat &p_rot, const Vector3 &p_scale) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, -1);
@@ -883,55 +814,47 @@ int Animation::transform_track_insert_key(int p_track, float p_time, const Vecto
}
void Animation::track_remove_key_at_position(int p_track, float p_pos) {
-
int idx = track_find_key(p_track, p_pos, true);
ERR_FAIL_COND(idx < 0);
track_remove_key(p_track, idx);
}
void Animation::track_remove_key(int p_track, int p_idx) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_idx, tt->transforms.size());
tt->transforms.remove(p_idx);
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_idx, vt->values.size());
vt->values.remove(p_idx);
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_idx, mt->methods.size());
mt->methods.remove(p_idx);
} break;
case TYPE_BEZIER: {
-
BezierTrack *bz = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX(p_idx, bz->values.size());
bz->values.remove(p_idx);
} break;
case TYPE_AUDIO: {
-
AudioTrack *ad = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX(p_idx, ad->values.size());
ad->values.remove(p_idx);
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *an = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX(p_idx, an->values.size());
an->values.remove(p_idx);
@@ -943,74 +866,79 @@ void Animation::track_remove_key(int p_track, int p_idx) {
}
int Animation::track_find_key(int p_track, float p_time, bool p_exact) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
int k = _find(tt->transforms, p_time);
- if (k < 0 || k >= tt->transforms.size())
+ if (k < 0 || k >= tt->transforms.size()) {
return -1;
- if (tt->transforms[k].time != p_time && p_exact)
+ }
+ if (tt->transforms[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
int k = _find(vt->values, p_time);
- if (k < 0 || k >= vt->values.size())
+ if (k < 0 || k >= vt->values.size()) {
return -1;
- if (vt->values[k].time != p_time && p_exact)
+ }
+ if (vt->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
int k = _find(mt->methods, p_time);
- if (k < 0 || k >= mt->methods.size())
+ if (k < 0 || k >= mt->methods.size()) {
return -1;
- if (mt->methods[k].time != p_time && p_exact)
+ }
+ if (mt->methods[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
int k = _find(bt->values, p_time);
- if (k < 0 || k >= bt->values.size())
+ if (k < 0 || k >= bt->values.size()) {
return -1;
- if (bt->values[k].time != p_time && p_exact)
+ }
+ if (bt->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
int k = _find(at->values, p_time);
- if (k < 0 || k >= at->values.size())
+ if (k < 0 || k >= at->values.size()) {
return -1;
- if (at->values[k].time != p_time && p_exact)
+ }
+ if (at->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
int k = _find(at->values, p_time);
- if (k < 0 || k >= at->values.size())
+ if (k < 0 || k >= at->values.size()) {
return -1;
- if (at->values[k].time != p_time && p_exact)
+ }
+ if (at->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
@@ -1020,33 +948,32 @@ int Animation::track_find_key(int p_track, float p_time, bool p_exact) const {
}
void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
Dictionary d = p_key;
Vector3 loc;
- if (d.has("location"))
+ if (d.has("location")) {
loc = d["location"];
+ }
Quat rot;
- if (d.has("rotation"))
+ if (d.has("rotation")) {
rot = d["rotation"];
+ }
Vector3 scale;
- if (d.has("scale"))
+ if (d.has("scale")) {
scale = d["scale"];
+ }
int idx = transform_track_insert_key(p_track, p_time, loc, rot, scale);
track_set_key_transition(p_track, idx, p_transition);
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
TKey<Variant> k;
@@ -1057,13 +984,12 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_COND(p_key.get_type() != Variant::DICTIONARY);
Dictionary d = p_key;
- ERR_FAIL_COND(!d.has("method") || d["method"].get_type() != Variant::STRING);
+ ERR_FAIL_COND(!d.has("method") || (d["method"].get_type() != Variant::STRING_NAME && d["method"].get_type() != Variant::STRING));
ERR_FAIL_COND(!d.has("args") || !d["args"].is_array());
MethodKey k;
@@ -1077,7 +1003,6 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
Array arr = p_key;
@@ -1094,7 +1019,6 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
Dictionary k = p_key;
@@ -1111,7 +1035,6 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
TKey<StringName> ak;
@@ -1127,40 +1050,32 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
}
int Animation::track_get_key_count(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
return tt->transforms.size();
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
return vt->values.size();
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
return mt->methods.size();
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
return bt->values.size();
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
return at->values.size();
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
return at->values.size();
} break;
@@ -1170,14 +1085,11 @@ int Animation::track_get_key_count(int p_track) const {
}
Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), Variant());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), Variant());
@@ -1189,14 +1101,12 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
return d;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), Variant());
return vt->values[p_key_idx].value;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), Variant());
Dictionary d;
@@ -1206,7 +1116,6 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), Variant());
@@ -1221,7 +1130,6 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
@@ -1233,7 +1141,6 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
@@ -1246,48 +1153,40 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
}
float Animation::track_get_key_time(int p_track, int p_key_idx) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1);
return tt->transforms[p_key_idx].time;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
return vt->values[p_key_idx].time;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
return mt->methods[p_key_idx].time;
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), -1);
return bt->values[p_key_idx].time;
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
return at->values[p_key_idx].time;
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
return at->values[p_key_idx].time;
@@ -1299,14 +1198,11 @@ float Animation::track_get_key_time(int p_track, int p_key_idx) const {
}
void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
TKey<TransformKey> key = tt->transforms[p_key_idx];
@@ -1316,7 +1212,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
TKey<Variant> key = vt->values[p_key_idx];
@@ -1326,7 +1221,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
MethodKey key = mt->methods[p_key_idx];
@@ -1336,7 +1230,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, bt->values.size());
TKey<BezierKey> key = bt->values[p_key_idx];
@@ -1346,7 +1239,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
TKey<AudioKey> key = at->values[p_key_idx];
@@ -1356,7 +1248,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
TKey<StringName> key = at->values[p_key_idx];
@@ -1371,42 +1262,34 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
}
float Animation::track_get_key_transition(int p_track, int p_key_idx) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1);
return tt->transforms[p_key_idx].transition;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
return vt->values[p_key_idx].transition;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
return mt->methods[p_key_idx].transition;
} break;
case TYPE_BEZIER: {
-
return 1; //bezier does not really use transitions
} break;
case TYPE_AUDIO: {
-
return 1; //audio does not really use transitions
} break;
case TYPE_ANIMATION: {
-
return 1; //animation does not really use transitions
} break;
}
@@ -1415,29 +1298,28 @@ float Animation::track_get_key_transition(int p_track, int p_key_idx) const {
}
void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p_value) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
Dictionary d = p_value;
- if (d.has("location"))
+ if (d.has("location")) {
tt->transforms.write[p_key_idx].value.loc = d["location"];
- if (d.has("rotation"))
+ }
+ if (d.has("rotation")) {
tt->transforms.write[p_key_idx].value.rot = d["rotation"];
- if (d.has("scale"))
+ }
+ if (d.has("scale")) {
tt->transforms.write[p_key_idx].value.scale = d["scale"];
+ }
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
@@ -1445,20 +1327,20 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
Dictionary d = p_value;
- if (d.has("method"))
+ if (d.has("method")) {
mt->methods.write[p_key_idx].method = d["method"];
- if (d.has("args"))
+ }
+ if (d.has("args")) {
mt->methods.write[p_key_idx].params = d["args"];
+ }
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, bt->values.size());
@@ -1473,7 +1355,6 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
@@ -1488,7 +1369,6 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
@@ -1501,27 +1381,22 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
}
void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_transition) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
tt->transforms.write[p_key_idx].transition = p_transition;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
vt->values.write[p_key_idx].transition = p_transition;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
mt->methods.write[p_key_idx].transition = p_transition;
@@ -1539,42 +1414,43 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra
template <class K>
int Animation::_find(const Vector<K> &p_keys, float p_time) const {
-
int len = p_keys.size();
- if (len == 0)
+ if (len == 0) {
return -2;
+ }
int low = 0;
int high = len - 1;
int middle = 0;
#ifdef DEBUG_ENABLED
- if (low > high)
+ if (low > high) {
ERR_PRINT("low > high, this may be a bug");
+ }
#endif
const K *keys = &p_keys[0];
while (low <= high) {
-
middle = (low + high) / 2;
if (Math::is_equal_approx(p_time, keys[middle].time)) { //match
return middle;
- } else if (p_time < keys[middle].time)
+ } else if (p_time < keys[middle].time) {
high = middle - 1; //search low end of array
- else
+ } else {
low = middle + 1; //search high end of array
+ }
}
- if (keys[middle].time > p_time)
+ if (keys[middle].time > p_time) {
middle--;
+ }
return middle;
}
Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const {
-
TransformKey ret;
ret.loc = _interpolate(p_a.loc, p_b.loc, p_c);
ret.rot = _interpolate(p_a.rot, p_b.rot, p_c);
@@ -1584,27 +1460,24 @@ Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p
}
Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const {
-
- return p_a.linear_interpolate(p_b, p_c);
+ return p_a.lerp(p_b, p_c);
}
-Quat Animation::_interpolate(const Quat &p_a, const Quat &p_b, float p_c) const {
+Quat Animation::_interpolate(const Quat &p_a, const Quat &p_b, float p_c) const {
return p_a.slerp(p_b, p_c);
}
-Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, float p_c) const {
+Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, float p_c) const {
Variant dst;
Variant::interpolate(p_a, p_b, p_c, dst);
return dst;
}
float Animation::_interpolate(const float &p_a, const float &p_b, float p_c) const {
-
return p_a * (1.0 - p_c) + p_b * p_c;
}
Animation::TransformKey Animation::_cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, float p_c) const {
-
Animation::TransformKey tk;
tk.loc = p_a.loc.cubic_interpolate(p_b.loc, p_pre_a.loc, p_post_b.loc, p_c);
@@ -1613,16 +1486,16 @@ Animation::TransformKey Animation::_cubic_interpolate(const Animation::Transform
return tk;
}
-Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const {
+Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const {
return p_a.cubic_interpolate(p_b, p_pre_a, p_post_b, p_c);
}
-Quat Animation::_cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const {
+Quat Animation::_cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const {
return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c);
}
-Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const {
+Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const {
Variant::Type type_a = p_a.get_type();
Variant::Type type_b = p_b.get_type();
Variant::Type type_pa = p_pre_a.get_type();
@@ -1635,7 +1508,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
vformat |= 1 << type_pa;
vformat |= 1 << type_pb;
- if (vformat == ((1 << Variant::INT) | (1 << Variant::REAL)) || vformat == (1 << Variant::REAL)) {
+ if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) {
//mix of real and int
real_t p0 = p_pre_a;
@@ -1653,14 +1526,11 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
(-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
} else if ((vformat & (vformat - 1))) {
-
return p_a; //can't interpolate, mix of types
}
switch (type_a) {
-
case Variant::VECTOR2: {
-
Vector2 a = p_a;
Vector2 b = p_b;
Vector2 pa = p_pre_a;
@@ -1669,7 +1539,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return a.cubic_interpolate(b, pa, pb, p_c);
}
case Variant::RECT2: {
-
Rect2 a = p_a;
Rect2 b = p_b;
Rect2 pa = p_pre_a;
@@ -1680,7 +1549,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
}
case Variant::VECTOR3: {
-
Vector3 a = p_a;
Vector3 b = p_b;
Vector3 pa = p_pre_a;
@@ -1689,7 +1557,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return a.cubic_interpolate(b, pa, pb, p_c);
}
case Variant::QUAT: {
-
Quat a = p_a;
Quat b = p_b;
Quat pa = p_pre_a;
@@ -1698,7 +1565,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return a.cubic_slerp(b, pa, pb, p_c);
}
case Variant::AABB: {
-
AABB a = p_a;
AABB b = p_b;
AABB pa = p_pre_a;
@@ -1709,31 +1575,31 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
}
default: {
-
return _interpolate(p_a, p_b, p_c);
}
}
}
-float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const {
+float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const {
return _interpolate(p_a, p_b, p_c);
}
template <class T>
-T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const {
-
+T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const {
int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end)
if (len <= 0) {
// (-1 or -2 returned originally) (plus one above)
// meaning no keys, or only key time is larger than length
- if (p_ok)
+ if (p_ok) {
*p_ok = false;
+ }
return T();
} else if (len == 1) { // one key found (0+1), return it
- if (p_ok)
+ if (p_ok) {
*p_ok = true;
+ }
return p_keys[0].value;
}
@@ -1749,28 +1615,27 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol
if (loop && p_loop_wrap) {
// loop
if (idx >= 0) {
-
if ((idx + 1) < len) {
-
next = idx + 1;
float delta = p_keys[next].time - p_keys[idx].time;
float from = p_time - p_keys[idx].time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
} else {
-
next = 0;
float delta = (length - p_keys[idx].time) + p_keys[next].time;
float from = p_time - p_keys[idx].time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
}
} else {
@@ -1778,51 +1643,53 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol
idx = len - 1;
next = 0;
float endtime = (length - p_keys[idx].time);
- if (endtime < 0) // may be keys past the end
+ if (endtime < 0) { // may be keys past the end
endtime = 0;
+ }
float delta = endtime + p_keys[next].time;
float from = endtime + p_time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
}
} else { // no loop
if (idx >= 0) {
-
if ((idx + 1) < len) {
-
next = idx + 1;
float delta = p_keys[next].time - p_keys[idx].time;
float from = p_time - p_keys[idx].time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
} else {
-
next = idx;
}
} else {
-
// only allow extending first key to anim start if looping
- if (loop)
+ if (loop) {
idx = next = 0;
- else
+ } else {
result = false;
+ }
}
}
- if (p_ok)
+ if (p_ok) {
*p_ok = result;
- if (!result)
+ }
+ if (!result) {
return T();
+ }
float tr = p_keys[idx].transition;
@@ -1832,39 +1699,37 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol
}
if (tr != 1.0) {
-
c = Math::ease(c, tr);
}
switch (p_interp) {
-
case INTERPOLATION_NEAREST: {
-
return p_keys[idx].value;
} break;
case INTERPOLATION_LINEAR: {
-
return _interpolate(p_keys[idx].value, p_keys[next].value, c);
} break;
case INTERPOLATION_CUBIC: {
int pre = idx - 1;
- if (pre < 0)
+ if (pre < 0) {
pre = 0;
+ }
int post = next + 1;
- if (post >= len)
+ if (post >= len) {
post = next;
+ }
return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c);
} break;
- default: return p_keys[idx].value;
+ default:
+ return p_keys[idx].value;
}
// do a barrel roll
}
Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER);
@@ -1875,23 +1740,26 @@ Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3
TransformKey tk = _interpolate(tt->transforms, p_time, tt->interpolation, tt->loop_wrap, &ok);
- if (!ok)
+ if (!ok) {
return ERR_UNAVAILABLE;
+ }
- if (r_loc)
+ if (r_loc) {
*r_loc = tk.loc;
+ }
- if (r_rot)
+ if (r_rot) {
*r_rot = tk.rot;
+ }
- if (r_scale)
+ if (r_scale) {
*r_scale = tk.scale;
+ }
return OK;
}
Variant Animation::value_track_interpolate(int p_track, float p_time) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_VALUE, Variant());
@@ -1902,7 +1770,6 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
Variant res = _interpolate(vt->values, p_time, (vt->update_mode == UPDATE_CONTINUOUS || vt->update_mode == UPDATE_CAPTURE) ? vt->interpolation : INTERPOLATION_NEAREST, vt->loop_wrap, &ok);
if (ok) {
-
return res;
}
@@ -1910,9 +1777,9 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
}
void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const {
-
- if (from_time != length && to_time == length)
+ if (from_time != length && to_time == length) {
to_time = length * 1.001; //include a little more if at the end
+ }
int to = _find(vt->values, to_time);
if (to >= 0 && from_time == to_time && vt->values[to].time == from_time) {
@@ -1923,29 +1790,30 @@ void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, floa
// can't really send the events == time, will be sent in the next frame.
// if event>=len then it will probably never be requested by the anim player.
- if (to >= 0 && vt->values[to].time >= to_time)
+ if (to >= 0 && vt->values[to].time >= to_time) {
to--;
+ }
- if (to < 0)
+ if (to < 0) {
return; // not bother
+ }
int from = _find(vt->values, from_time);
// position in the right first event.+
- if (from < 0 || vt->values[from].time < from_time)
+ if (from < 0 || vt->values[from].time < from_time) {
from++;
+ }
int max = vt->values.size();
for (int i = from; i <= to; i++) {
-
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
p_indices->push_back(i);
}
}
void Animation::value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_VALUE);
@@ -1955,11 +1823,11 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
float from_time = p_time - p_delta;
float to_time = p_time;
- if (from_time > to_time)
+ if (from_time > to_time) {
SWAP(from_time, to_time);
+ }
if (loop) {
-
from_time = Math::fposmod(from_time, length);
to_time = Math::fposmod(to_time, length);
@@ -1970,23 +1838,25 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
return;
}
} else {
-
- if (from_time < 0)
+ if (from_time < 0) {
from_time = 0;
- if (from_time > length)
+ }
+ if (from_time > length) {
from_time = length;
+ }
- if (to_time < 0)
+ if (to_time < 0) {
to_time = 0;
- if (to_time > length)
+ }
+ if (to_time > length) {
to_time = length;
+ }
}
_value_track_get_key_indices_in_range(vt, from_time, to_time, p_indices);
}
void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_VALUE);
@@ -1997,7 +1867,6 @@ void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
}
Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), UPDATE_CONTINUOUS);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_VALUE, UPDATE_CONTINUOUS);
@@ -2008,97 +1877,93 @@ Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const
template <class T>
void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, float from_time, float to_time, List<int> *p_indices) const {
-
- if (from_time != length && to_time == length)
+ if (from_time != length && to_time == length) {
to_time = length * 1.01; //include a little more if at the end
+ }
int to = _find(p_array, to_time);
// can't really send the events == time, will be sent in the next frame.
// if event>=len then it will probably never be requested by the anim player.
- if (to >= 0 && p_array[to].time >= to_time)
+ if (to >= 0 && p_array[to].time >= to_time) {
to--;
+ }
- if (to < 0)
+ if (to < 0) {
return; // not bother
+ }
int from = _find(p_array, from_time);
// position in the right first event.+
- if (from < 0 || p_array[from].time < from_time)
+ if (from < 0 || p_array[from].time < from_time) {
from++;
+ }
int max = p_array.size();
for (int i = from; i <= to; i++) {
-
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
p_indices->push_back(i);
}
}
void Animation::track_get_key_indices_in_range(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
-
ERR_FAIL_INDEX(p_track, tracks.size());
const Track *t = tracks[p_track];
float from_time = p_time - p_delta;
float to_time = p_time;
- if (from_time > to_time)
+ if (from_time > to_time) {
SWAP(from_time, to_time);
+ }
if (loop) {
-
- if (from_time > length || from_time < 0)
+ if (from_time > length || from_time < 0) {
from_time = Math::fposmod(from_time, length);
+ }
- if (to_time > length || to_time < 0)
+ if (to_time > length || to_time < 0) {
to_time = Math::fposmod(to_time, length);
+ }
if (from_time > to_time) {
// handle loop by splitting
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
const TransformTrack *tt = static_cast<const TransformTrack *>(t);
_track_get_key_indices_in_range(tt->transforms, from_time, length, p_indices);
_track_get_key_indices_in_range(tt->transforms, 0, to_time, p_indices);
} break;
case TYPE_VALUE: {
-
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
_track_get_key_indices_in_range(vt->values, from_time, length, p_indices);
_track_get_key_indices_in_range(vt->values, 0, to_time, p_indices);
} break;
case TYPE_METHOD: {
-
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
_track_get_key_indices_in_range(mt->methods, from_time, length, p_indices);
_track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices);
} break;
case TYPE_BEZIER: {
-
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
_track_get_key_indices_in_range(bz->values, from_time, length, p_indices);
_track_get_key_indices_in_range(bz->values, 0, to_time, p_indices);
} break;
case TYPE_AUDIO: {
-
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
_track_get_key_indices_in_range(ad->values, from_time, length, p_indices);
_track_get_key_indices_in_range(ad->values, 0, to_time, p_indices);
} break;
case TYPE_ANIMATION: {
-
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
_track_get_key_indices_in_range(an->values, from_time, length, p_indices);
_track_get_key_indices_in_range(an->values, 0, to_time, p_indices);
@@ -2108,52 +1973,48 @@ void Animation::track_get_key_indices_in_range(int p_track, float p_time, float
return;
}
} else {
-
- if (from_time < 0)
+ if (from_time < 0) {
from_time = 0;
- if (from_time > length)
+ }
+ if (from_time > length) {
from_time = length;
+ }
- if (to_time < 0)
+ if (to_time < 0) {
to_time = 0;
- if (to_time > length)
+ }
+ if (to_time > length) {
to_time = length;
+ }
}
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
const TransformTrack *tt = static_cast<const TransformTrack *>(t);
_track_get_key_indices_in_range(tt->transforms, from_time, to_time, p_indices);
} break;
case TYPE_VALUE: {
-
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
_track_get_key_indices_in_range(vt->values, from_time, to_time, p_indices);
} break;
case TYPE_METHOD: {
-
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
_track_get_key_indices_in_range(mt->methods, from_time, to_time, p_indices);
} break;
case TYPE_BEZIER: {
-
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
_track_get_key_indices_in_range(bz->values, from_time, to_time, p_indices);
} break;
case TYPE_AUDIO: {
-
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
_track_get_key_indices_in_range(ad->values, from_time, to_time, p_indices);
} break;
case TYPE_ANIMATION: {
-
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
_track_get_key_indices_in_range(an->values, from_time, to_time, p_indices);
@@ -2162,38 +2023,39 @@ void Animation::track_get_key_indices_in_range(int p_track, float p_time, float
}
void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const {
-
- if (from_time != length && to_time == length)
+ if (from_time != length && to_time == length) {
to_time = length * 1.01; //include a little more if at the end
+ }
int to = _find(mt->methods, to_time);
// can't really send the events == time, will be sent in the next frame.
// if event>=len then it will probably never be requested by the anim player.
- if (to >= 0 && mt->methods[to].time >= to_time)
+ if (to >= 0 && mt->methods[to].time >= to_time) {
to--;
+ }
- if (to < 0)
+ if (to < 0) {
return; // not bother
+ }
int from = _find(mt->methods, from_time);
// position in the right first event.+
- if (from < 0 || mt->methods[from].time < from_time)
+ if (from < 0 || mt->methods[from].time < from_time) {
from++;
+ }
int max = mt->methods.size();
for (int i = from; i <= to; i++) {
-
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
p_indices->push_back(i);
}
}
void Animation::method_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_METHOD);
@@ -2203,16 +2065,18 @@ void Animation::method_track_get_key_indices(int p_track, float p_time, float p_
float from_time = p_time - p_delta;
float to_time = p_time;
- if (from_time > to_time)
+ if (from_time > to_time) {
SWAP(from_time, to_time);
+ }
if (loop) {
-
- if (from_time > length || from_time < 0)
+ if (from_time > length || from_time < 0) {
from_time = Math::fposmod(from_time, length);
+ }
- if (to_time > length || to_time < 0)
+ if (to_time > length || to_time < 0) {
to_time = Math::fposmod(to_time, length);
+ }
if (from_time > to_time) {
// handle loop by splitting
@@ -2221,22 +2085,25 @@ void Animation::method_track_get_key_indices(int p_track, float p_time, float p_
return;
}
} else {
-
- if (from_time < 0)
+ if (from_time < 0) {
from_time = 0;
- if (from_time > length)
+ }
+ if (from_time > length) {
from_time = length;
+ }
- if (to_time < 0)
+ if (to_time < 0) {
to_time = 0;
- if (to_time > length)
+ }
+ if (to_time > length) {
to_time = length;
+ }
}
_method_track_get_key_indices_in_range(mt, from_time, to_time, p_indices);
}
-Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
+Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector<Variant>());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_METHOD, Vector<Variant>());
@@ -2249,8 +2116,8 @@ Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) c
return mk.params;
}
-StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
+StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_METHOD, StringName());
@@ -2263,7 +2130,6 @@ StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
}
int Animation::bezier_track_insert_key(int p_track, float p_time, float p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1);
@@ -2290,7 +2156,6 @@ int Animation::bezier_track_insert_key(int p_track, float p_time, float p_value,
}
void Animation::bezier_track_set_key_value(int p_track, int p_index, float p_value) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -2304,7 +2169,6 @@ void Animation::bezier_track_set_key_value(int p_track, int p_index, float p_val
}
void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -2319,8 +2183,8 @@ void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const V
}
emit_changed();
}
-void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle) {
+void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle) {
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -2335,8 +2199,8 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const
}
emit_changed();
}
-float Animation::bezier_track_get_key_value(int p_track, int p_index) const {
+float Animation::bezier_track_get_key_value(int p_track, int p_index) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, 0);
@@ -2347,8 +2211,8 @@ float Animation::bezier_track_get_key_value(int p_track, int p_index) const {
return bt->values[p_index].value.value;
}
-Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const {
+Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
@@ -2359,8 +2223,8 @@ Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) cons
return bt->values[p_index].value.in_handle;
}
-Vector2 Animation::bezier_track_get_key_out_handle(int p_track, int p_index) const {
+Vector2 Animation::bezier_track_get_key_out_handle(int p_track, int p_index) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
@@ -2430,7 +2294,6 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
//narrow high and low as much as possible
for (int i = 0; i < iterations; i++) {
-
middle = (low + high) / 2;
Vector2 interp = _bezier_interp(middle, start, start_out, end_in, end);
@@ -2447,11 +2310,10 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
Vector2 high_pos = _bezier_interp(high, start, start_out, end_in, end);
float c = (t - low_pos.x) / (high_pos.x - low_pos.x);
- return low_pos.linear_interpolate(high_pos, c).y;
+ return low_pos.lerp(high_pos, c).y;
}
int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_stream, float p_start_offset, float p_end_offset) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, -1);
@@ -2462,11 +2324,13 @@ int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_st
k.time = p_time;
k.value.stream = p_stream;
k.value.start_offset = p_start_offset;
- if (k.value.start_offset < 0)
+ if (k.value.start_offset < 0) {
k.value.start_offset = 0;
+ }
k.value.end_offset = p_end_offset;
- if (k.value.end_offset < 0)
+ if (k.value.end_offset < 0) {
k.value.end_offset = 0;
+ }
int key = _insert(p_time, at->values, k);
@@ -2476,7 +2340,6 @@ int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_st
}
void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_stream) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_AUDIO);
@@ -2491,7 +2354,6 @@ void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_
}
void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p_offset) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_AUDIO);
@@ -2500,8 +2362,9 @@ void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p
ERR_FAIL_INDEX(p_key, at->values.size());
- if (p_offset < 0)
+ if (p_offset < 0) {
p_offset = 0;
+ }
at->values.write[p_key].value.start_offset = p_offset;
@@ -2509,7 +2372,6 @@ void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p
}
void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_offset) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_AUDIO);
@@ -2518,8 +2380,9 @@ void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_o
ERR_FAIL_INDEX(p_key, at->values.size());
- if (p_offset < 0)
+ if (p_offset < 0) {
p_offset = 0;
+ }
at->values.write[p_key].value.end_offset = p_offset;
@@ -2527,7 +2390,6 @@ void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_o
}
RES Animation::audio_track_get_key_stream(int p_track, int p_key) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), RES());
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, RES());
@@ -2538,8 +2400,8 @@ RES Animation::audio_track_get_key_stream(int p_track, int p_key) const {
return at->values[p_key].value.stream;
}
-float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const {
+float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
@@ -2550,8 +2412,8 @@ float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const
return at->values[p_key].value.start_offset;
}
-float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
+float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
@@ -2566,7 +2428,6 @@ float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
//
int Animation::animation_track_insert_key(int p_track, float p_time, const StringName &p_animation) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, -1);
@@ -2585,7 +2446,6 @@ int Animation::animation_track_insert_key(int p_track, float p_time, const Strin
}
void Animation::animation_track_set_key_animation(int p_track, int p_key, const StringName &p_animation) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_ANIMATION);
@@ -2600,7 +2460,6 @@ void Animation::animation_track_set_key_animation(int p_track, int p_key, const
}
StringName Animation::animation_track_get_key_animation(int p_track, int p_key) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, StringName());
@@ -2613,57 +2472,49 @@ StringName Animation::animation_track_get_key_animation(int p_track, int p_key)
}
void Animation::set_length(float p_length) {
-
if (p_length < ANIM_MIN_LENGTH) {
p_length = ANIM_MIN_LENGTH;
}
length = p_length;
emit_changed();
}
-float Animation::get_length() const {
+float Animation::get_length() const {
return length;
}
void Animation::set_loop(bool p_enabled) {
-
loop = p_enabled;
emit_changed();
}
-bool Animation::has_loop() const {
+bool Animation::has_loop() const {
return loop;
}
void Animation::track_set_imported(int p_track, bool p_imported) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
tracks[p_track]->imported = p_imported;
}
bool Animation::track_is_imported(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
return tracks[p_track]->imported;
}
void Animation::track_set_enabled(int p_track, bool p_enabled) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
tracks[p_track]->enabled = p_enabled;
emit_changed();
}
bool Animation::track_is_enabled(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
return tracks[p_track]->enabled;
}
void Animation::track_move_up(int p_track) {
-
if (p_track >= 0 && p_track < (tracks.size() - 1)) {
-
SWAP(tracks.write[p_track], tracks.write[p_track + 1]);
}
@@ -2672,9 +2523,7 @@ void Animation::track_move_up(int p_track) {
}
void Animation::track_move_down(int p_track) {
-
if (p_track > 0 && p_track < tracks.size()) {
-
SWAP(tracks.write[p_track], tracks.write[p_track - 1]);
}
@@ -2683,11 +2532,11 @@ void Animation::track_move_down(int p_track) {
}
void Animation::track_move_to(int p_track, int p_to_index) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
ERR_FAIL_INDEX(p_to_index, tracks.size() + 1);
- if (p_track == p_to_index || p_track == p_to_index - 1)
+ if (p_track == p_to_index || p_track == p_to_index - 1) {
return;
+ }
Track *track = tracks.get(p_track);
tracks.remove(p_track);
@@ -2699,11 +2548,11 @@ void Animation::track_move_to(int p_track, int p_to_index) {
}
void Animation::track_swap(int p_track, int p_with_track) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
ERR_FAIL_INDEX(p_with_track, tracks.size());
- if (p_track == p_with_track)
+ if (p_track == p_with_track) {
return;
+ }
SWAP(tracks.write[p_track], tracks.write[p_with_track]);
emit_changed();
@@ -2711,13 +2560,11 @@ void Animation::track_swap(int p_track, int p_with_track) {
}
void Animation::set_step(float p_step) {
-
step = p_step;
emit_changed();
}
float Animation::get_step() const {
-
return step;
}
@@ -2732,14 +2579,16 @@ void Animation::copy_track(int p_track, Ref<Animation> p_to_animation) {
p_to_animation->track_set_enabled(dst_track, track_is_enabled(p_track));
p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(p_track));
p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(p_track));
- p_to_animation->value_track_set_update_mode(dst_track, value_track_get_update_mode(p_track));
+ if (track_get_type(p_track) == TYPE_VALUE) {
+ p_to_animation->value_track_set_update_mode(dst_track, value_track_get_update_mode(p_track));
+ }
+
for (int i = 0; i < track_get_key_count(p_track); i++) {
p_to_animation->track_insert_key(dst_track, track_get_key_time(p_track, i), track_get_key_value(p_track, i), track_get_key_transition(p_track, i));
}
}
void Animation::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("remove_track", "track_idx"), &Animation::remove_track);
ClassDB::bind_method(D_METHOD("get_track_count"), &Animation::get_track_count);
@@ -2825,9 +2674,9 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
ClassDB::bind_method(D_METHOD("copy_track", "track_idx", "to_animation"), &Animation::copy_track);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step");
ADD_SIGNAL(MethodInfo("tracks_changed"));
@@ -2849,9 +2698,9 @@ void Animation::_bind_methods() {
}
void Animation::clear() {
-
- for (int i = 0; i < tracks.size(); i++)
+ for (int i = 0; i < tracks.size(); i++) {
memdelete(tracks[i]);
+ }
tracks.clear();
loop = false;
length = 1;
@@ -2860,7 +2709,6 @@ void Animation::clear() {
}
bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm) {
-
real_t c = (t1.time - t0.time) / (t2.time - t0.time);
real_t t[3] = { -1, -1, -1 };
@@ -2878,7 +2726,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
} else {
-
Vector3 pd = (v2 - v0);
float d0 = pd.dot(v0);
float d1 = pd.dot(v1);
@@ -2888,14 +2735,15 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
Vector3 s[2] = { v0, v2 };
- real_t d = Geometry::get_closest_point_to_segment(v1, s).distance_to(v1);
+ real_t d = Geometry3D::get_closest_point_to_segment(v1, s).distance_to(v1);
if (d > pd.length() * p_alowed_linear_err) {
return false; //beyond allowed error for colinearity
}
- if (p_norm != Vector3() && Math::acos(pd.normalized().dot(p_norm)) > p_alowed_angular_err)
+ if (p_norm != Vector3() && Math::acos(pd.normalized().dot(p_norm)) > p_alowed_angular_err) {
return false;
+ }
t[0] = (d1 - d0) / (d2 - d0);
}
@@ -2910,12 +2758,11 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
//localize both to rotation from q0
if (q0.is_equal_approx(q2)) {
-
- if (!q0.is_equal_approx(q1))
+ if (!q0.is_equal_approx(q1)) {
return false;
+ }
} else {
-
Quat r02 = (q0.inverse() * q2).normalized();
Quat r01 = (q0.inverse() * q1).normalized();
@@ -2925,8 +2772,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
r02.get_axis_angle(v02, a02);
r01.get_axis_angle(v01, a01);
- if (Math::abs(a02) > p_max_optimizable_angle)
+ if (Math::abs(a02) > p_max_optimizable_angle) {
return false;
+ }
if (v01.dot(v02) < 0) {
//make sure both rotations go the same way to compare
@@ -2946,8 +2794,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
real_t tr = a01 / a02;
- if (tr < 0 || tr > 1)
+ if (tr < 0 || tr > 1) {
return false; //rotating too much or too less
+ }
t[1] = tr;
}
@@ -2967,7 +2816,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
} else {
-
Vector3 pd = (v2 - v0);
float d0 = pd.dot(v0);
float d1 = pd.dot(v1);
@@ -2977,7 +2825,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
Vector3 s[2] = { v0, v2 };
- real_t d = Geometry::get_closest_point_to_segment(v1, s).distance_to(v1);
+ real_t d = Geometry3D::get_closest_point_to_segment(v1, s).distance_to(v1);
if (d > pd.length() * p_alowed_linear_err) {
return false; //beyond allowed error for colinearity
@@ -2989,10 +2837,8 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
bool erase = false;
if (t[0] == -1 && t[1] == -1 && t[2] == -1) {
-
erase = true;
} else {
-
erase = true;
real_t lt = -1;
for (int j = 0; j < 3; j++) {
@@ -3001,8 +2847,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
lt = t[j]; //official t
//validate rest
for (int k = j + 1; k < 3; k++) {
- if (t[k] == -1)
+ if (t[k] == -1) {
continue;
+ }
if (Math::abs(lt - t[k]) > p_alowed_linear_err) {
erase = false;
@@ -3016,7 +2863,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
ERR_FAIL_COND_V(lt == -1, false);
if (erase) {
-
if (Math::abs(lt - c) > p_alowed_linear_err) {
//todo, evaluate changing the transition if this fails?
//this could be done as a second pass and would be
@@ -3030,7 +2876,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) {
-
ERR_FAIL_INDEX(p_idx, tracks.size());
ERR_FAIL_COND(tracks[p_idx]->type != TYPE_TRANSFORM);
TransformTrack *tt = static_cast<TransformTrack *>(tracks[p_idx]);
@@ -3040,7 +2885,6 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err,
Vector3 norm;
for (int i = 1; i < tt->transforms.size() - 1; i++) {
-
TKey<TransformKey> &t0 = tt->transforms.write[i - 1];
TKey<TransformKey> &t1 = tt->transforms.write[i];
TKey<TransformKey> &t2 = tt->transforms.write[i + 1];
@@ -3056,7 +2900,6 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err,
}
if (erase) {
-
if (!prev_erased) {
first_erased = t1;
prev_erased = true;
@@ -3073,23 +2916,21 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err,
}
void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) {
-
for (int i = 0; i < tracks.size(); i++) {
-
- if (tracks[i]->type == TYPE_TRANSFORM)
+ if (tracks[i]->type == TYPE_TRANSFORM) {
_transform_track_optimize(i, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle);
+ }
}
}
Animation::Animation() {
-
step = 0.1;
loop = false;
length = 1;
}
Animation::~Animation() {
-
- for (int i = 0; i < tracks.size(); i++)
+ for (int i = 0; i < tracks.size(); i++) {
memdelete(tracks[i]);
+ }
}
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 6ac0ea04d9..722a400fd6 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -34,7 +34,6 @@
#include "core/resource.h"
class Animation : public Resource {
-
GDCLASS(Animation, Resource);
RES_BASE_EXTENSION("anim");
@@ -64,7 +63,6 @@ public:
private:
struct Track {
-
TrackType type;
InterpolationType interpolation;
bool loop_wrap;
@@ -81,21 +79,21 @@ private:
};
struct Key {
-
float transition;
float time; // time in secs
- Key() { transition = 1; }
+ Key() {
+ transition = 1;
+ time = 0;
+ }
};
// transform key holds either Vector3 or Quaternion
template <class T>
struct TKey : public Key {
-
T value;
};
struct TransformKey {
-
Vector3 loc;
Quat rot;
Vector3 scale;
@@ -104,8 +102,7 @@ private:
/* TRANSFORM TRACK */
struct TransformTrack : public Track {
-
- Vector<TKey<TransformKey> > transforms;
+ Vector<TKey<TransformKey>> transforms;
TransformTrack() { type = TYPE_TRANSFORM; }
};
@@ -113,10 +110,9 @@ private:
/* PROPERTY VALUE TRACK */
struct ValueTrack : public Track {
-
UpdateMode update_mode;
bool update_on_seek;
- Vector<TKey<Variant> > values;
+ Vector<TKey<Variant>> values;
ValueTrack() {
type = TYPE_VALUE;
@@ -127,13 +123,11 @@ private:
/* METHOD TRACK */
struct MethodKey : public Key {
-
StringName method;
Vector<Variant> params;
};
struct MethodTrack : public Track {
-
Vector<MethodKey> methods;
MethodTrack() { type = TYPE_METHOD; }
};
@@ -147,8 +141,7 @@ private:
};
struct BezierTrack : public Track {
-
- Vector<TKey<BezierKey> > values;
+ Vector<TKey<BezierKey>> values;
BezierTrack() {
type = TYPE_BEZIER;
@@ -168,8 +161,7 @@ private:
};
struct AudioTrack : public Track {
-
- Vector<TKey<AudioKey> > values;
+ Vector<TKey<AudioKey>> values;
AudioTrack() {
type = TYPE_AUDIO;
@@ -179,8 +171,7 @@ private:
/* AUDIO TRACK */
struct AnimationTrack : public Track {
-
- Vector<TKey<StringName> > values;
+ Vector<TKey<StringName>> values;
AnimationTrack() {
type = TYPE_ANIMATION;
@@ -216,7 +207,7 @@ private:
_FORCE_INLINE_ float _cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const;
template <class T>
- _FORCE_INLINE_ T _interpolate(const Vector<TKey<T> > &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const;
+ _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const;
template <class T>
_FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, float from_time, float to_time, List<int> *p_indices) const;
@@ -242,26 +233,22 @@ private:
return ret;
}
- PoolVector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const {
-
+ Vector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const {
List<int> idxs;
value_track_get_key_indices(p_track, p_time, p_delta, &idxs);
- PoolVector<int> idxr;
+ Vector<int> idxr;
for (List<int>::Element *E = idxs.front(); E; E = E->next()) {
-
idxr.push_back(E->get());
}
return idxr;
}
- PoolVector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const {
-
+ Vector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const {
List<int> idxs;
method_track_get_key_indices(p_track, p_time, p_delta, &idxs);
- PoolVector<int> idxr;
+ Vector<int> idxr;
for (List<int>::Element *E = idxs.front(); E; E = E->next()) {
-
idxr.push_back(E->get());
}
return idxr;
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index e8cb40154e..f02e7987a9 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -34,7 +34,6 @@
#include "core/os/file_access.h"
void AudioStreamPlaybackSample::start(float p_from_pos) {
-
if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) {
//no seeking in IMA_ADPCM
for (int i = 0; i < 2; i++) {
@@ -57,28 +56,25 @@ void AudioStreamPlaybackSample::start(float p_from_pos) {
}
void AudioStreamPlaybackSample::stop() {
-
active = false;
}
bool AudioStreamPlaybackSample::is_playing() const {
-
return active;
}
int AudioStreamPlaybackSample::get_loop_count() const {
-
return 0;
}
float AudioStreamPlaybackSample::get_playback_position() const {
-
return float(offset >> MIX_FRAC_BITS) / base->mix_rate;
}
-void AudioStreamPlaybackSample::seek(float p_time) {
- if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM)
+void AudioStreamPlaybackSample::seek(float p_time) {
+ if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) {
return; //no seeking in ima-adpcm
+ }
float max = base->get_length();
if (p_time < 0) {
@@ -92,22 +88,20 @@ void AudioStreamPlaybackSample::seek(float p_time) {
template <class Depth, bool is_stereo, bool is_ima_adpcm>
void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) {
-
// this function will be compiled branchless by any decent compiler
int32_t final, final_r, next, next_r;
while (amount) {
amount--;
int64_t pos = offset >> MIX_FRAC_BITS;
- if (is_stereo && !is_ima_adpcm)
+ if (is_stereo && !is_ima_adpcm) {
pos <<= 1;
+ }
if (is_ima_adpcm) {
-
int64_t sample_pos = pos + ima_adpcm[0].window_ofs;
while (sample_pos > ima_adpcm[0].last_nibble) {
-
static const int16_t _ima_adpcm_step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
@@ -126,7 +120,6 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
};
for (int i = 0; i < (is_stereo ? 2 : 1); i++) {
-
int16_t nibble, diff, step;
ima_adpcm[i].last_nibble++;
@@ -138,30 +131,36 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
step = _ima_adpcm_step_table[ima_adpcm[i].step_index];
ima_adpcm[i].step_index += _ima_adpcm_index_table[nibble];
- if (ima_adpcm[i].step_index < 0)
+ if (ima_adpcm[i].step_index < 0) {
ima_adpcm[i].step_index = 0;
- if (ima_adpcm[i].step_index > 88)
+ }
+ if (ima_adpcm[i].step_index > 88) {
ima_adpcm[i].step_index = 88;
+ }
diff = step >> 3;
- if (nibble & 1)
+ if (nibble & 1) {
diff += step >> 2;
- if (nibble & 2)
+ }
+ if (nibble & 2) {
diff += step >> 1;
- if (nibble & 4)
+ }
+ if (nibble & 4) {
diff += step;
- if (nibble & 8)
+ }
+ if (nibble & 8) {
diff = -diff;
+ }
ima_adpcm[i].predictor += diff;
- if (ima_adpcm[i].predictor < -0x8000)
+ if (ima_adpcm[i].predictor < -0x8000) {
ima_adpcm[i].predictor = -0x8000;
- else if (ima_adpcm[i].predictor > 0x7FFF)
+ } else if (ima_adpcm[i].predictor > 0x7FFF) {
ima_adpcm[i].predictor = 0x7FFF;
+ }
/* store loop if there */
if (ima_adpcm[i].last_nibble == ima_adpcm[i].loop_pos) {
-
ima_adpcm[i].loop_step_index = ima_adpcm[i].step_index;
ima_adpcm[i].loop_predictor = ima_adpcm[i].predictor;
}
@@ -177,17 +176,18 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
} else {
final = p_src[pos];
- if (is_stereo)
+ if (is_stereo) {
final_r = p_src[pos + 1];
+ }
if (sizeof(Depth) == 1) { /* conditions will not exist anymore when compiled! */
final <<= 8;
- if (is_stereo)
+ if (is_stereo) {
final_r <<= 8;
+ }
}
if (is_stereo) {
-
next = p_src[pos + 2];
next_r = p_src[pos + 3];
} else {
@@ -196,15 +196,17 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
if (sizeof(Depth) == 1) {
next <<= 8;
- if (is_stereo)
+ if (is_stereo) {
next_r <<= 8;
+ }
}
int32_t frac = int64_t(offset & MIX_FRAC_MASK);
final = final + ((next - final) * frac >> MIX_FRAC_BITS);
- if (is_stereo)
+ if (is_stereo) {
final_r = final_r + ((next_r - final_r) * frac >> MIX_FRAC_BITS);
+ }
}
if (!is_stereo) {
@@ -220,7 +222,6 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
}
void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
-
if (!base->data || !active) {
for (int i = 0; i < p_frames; i++) {
p_buffer[i] = AudioFrame(0, 0);
@@ -230,9 +231,15 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
int len = base->data_bytes;
switch (base->format) {
- case AudioStreamSample::FORMAT_8_BITS: len /= 1; break;
- case AudioStreamSample::FORMAT_16_BITS: len /= 2; break;
- case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break;
+ case AudioStreamSample::FORMAT_8_BITS:
+ len /= 1;
+ break;
+ case AudioStreamSample::FORMAT_16_BITS:
+ len /= 2;
+ break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM:
+ len *= 2;
+ break;
}
if (base->stereo) {
@@ -258,7 +265,7 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
float srate = base->mix_rate;
srate *= p_rate_scale;
float fincrement = srate / base_rate;
- int32_t increment = int32_t(fincrement * MIX_FRAC_LEN);
+ int32_t increment = int32_t(MAX(fincrement * MIX_FRAC_LEN, 1));
increment *= sign;
//looping
@@ -273,7 +280,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
AudioFrame *dst_buff = p_buffer;
if (format == AudioStreamSample::FORMAT_IMA_ADPCM) {
-
if (loop_format != AudioStreamSample::LOOP_DISABLED) {
ima_adpcm[0].loop_pos = loop_begin_fp >> MIX_FRAC_BITS;
ima_adpcm[1].loop_pos = loop_begin_fp >> MIX_FRAC_BITS;
@@ -282,7 +288,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
}
while (todo > 0) {
-
int64_t limit = 0;
int32_t target = 0, aux = 0;
@@ -305,7 +310,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
} else {
/* check for sample not reaching beginning */
if (offset < 0) {
-
active = false;
break;
}
@@ -337,7 +341,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
} else {
/* no loop, check for end of sample */
if (offset >= length_fp) {
-
active = false;
break;
}
@@ -363,24 +366,26 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
switch (base->format) {
case AudioStreamSample::FORMAT_8_BITS: {
-
- if (is_stereo)
+ if (is_stereo) {
do_resample<int8_t, true, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
- else
+ } else {
do_resample<int8_t, false, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
+ }
} break;
case AudioStreamSample::FORMAT_16_BITS: {
- if (is_stereo)
+ if (is_stereo) {
do_resample<int16_t, true, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm);
- else
+ } else {
do_resample<int16_t, false, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm);
+ }
} break;
case AudioStreamSample::FORMAT_IMA_ADPCM: {
- if (is_stereo)
+ if (is_stereo) {
do_resample<int8_t, true, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
- else
+ } else {
do_resample<int8_t, false, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
+ }
} break;
}
@@ -398,7 +403,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
}
AudioStreamPlaybackSample::AudioStreamPlaybackSample() {
-
active = false;
offset = 0;
sign = 1;
@@ -407,67 +411,66 @@ AudioStreamPlaybackSample::AudioStreamPlaybackSample() {
/////////////////////
void AudioStreamSample::set_format(Format p_format) {
-
format = p_format;
}
AudioStreamSample::Format AudioStreamSample::get_format() const {
-
return format;
}
void AudioStreamSample::set_loop_mode(LoopMode p_loop_mode) {
-
loop_mode = p_loop_mode;
}
-AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const {
+AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const {
return loop_mode;
}
void AudioStreamSample::set_loop_begin(int p_frame) {
-
loop_begin = p_frame;
}
-int AudioStreamSample::get_loop_begin() const {
+int AudioStreamSample::get_loop_begin() const {
return loop_begin;
}
void AudioStreamSample::set_loop_end(int p_frame) {
-
loop_end = p_frame;
}
-int AudioStreamSample::get_loop_end() const {
+int AudioStreamSample::get_loop_end() const {
return loop_end;
}
void AudioStreamSample::set_mix_rate(int p_hz) {
-
ERR_FAIL_COND(p_hz == 0);
mix_rate = p_hz;
}
-int AudioStreamSample::get_mix_rate() const {
+int AudioStreamSample::get_mix_rate() const {
return mix_rate;
}
-void AudioStreamSample::set_stereo(bool p_enable) {
+void AudioStreamSample::set_stereo(bool p_enable) {
stereo = p_enable;
}
-bool AudioStreamSample::is_stereo() const {
+bool AudioStreamSample::is_stereo() const {
return stereo;
}
float AudioStreamSample::get_length() const {
-
int len = data_bytes;
switch (format) {
- case AudioStreamSample::FORMAT_8_BITS: len /= 1; break;
- case AudioStreamSample::FORMAT_16_BITS: len /= 2; break;
- case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break;
+ case AudioStreamSample::FORMAT_8_BITS:
+ len /= 1;
+ break;
+ case AudioStreamSample::FORMAT_16_BITS:
+ len /= 2;
+ break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM:
+ len *= 2;
+ break;
}
if (stereo) {
@@ -477,40 +480,37 @@ float AudioStreamSample::get_length() const {
return float(len) / mix_rate;
}
-void AudioStreamSample::set_data(const PoolVector<uint8_t> &p_data) {
-
+void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) {
AudioServer::get_singleton()->lock();
if (data) {
- AudioServer::get_singleton()->audio_data_free(data);
- data = NULL;
+ memfree(data);
+ data = nullptr;
data_bytes = 0;
}
int datalen = p_data.size();
if (datalen) {
-
- PoolVector<uint8_t>::Read r = p_data.read();
+ const uint8_t *r = p_data.ptr();
int alloc_len = datalen + DATA_PAD * 2;
- data = AudioServer::get_singleton()->audio_data_alloc(alloc_len); //alloc with some padding for interpolation
+ data = memalloc(alloc_len); //alloc with some padding for interpolation
zeromem(data, alloc_len);
uint8_t *dataptr = (uint8_t *)data;
- copymem(dataptr + DATA_PAD, r.ptr(), datalen);
+ copymem(dataptr + DATA_PAD, r, datalen);
data_bytes = datalen;
}
AudioServer::get_singleton()->unlock();
}
-PoolVector<uint8_t> AudioStreamSample::get_data() const {
- PoolVector<uint8_t> pv;
+Vector<uint8_t> AudioStreamSample::get_data() const {
+ Vector<uint8_t> pv;
if (data) {
pv.resize(data_bytes);
{
-
- PoolVector<uint8_t>::Write w = pv.write();
+ uint8_t *w = pv.ptrw();
uint8_t *dataptr = (uint8_t *)data;
- copymem(w.ptr(), dataptr + DATA_PAD, data_bytes);
+ copymem(w, dataptr + DATA_PAD, data_bytes);
}
}
@@ -519,7 +519,7 @@ PoolVector<uint8_t> AudioStreamSample::get_data() const {
Error AudioStreamSample::save_to_wav(const String &p_path) {
if (format == AudioStreamSample::FORMAT_IMA_ADPCM) {
- WARN_PRINTS("Saving IMA_ADPC samples are not supported yet");
+ WARN_PRINT("Saving IMA_ADPC samples are not supported yet");
return ERR_UNAVAILABLE;
}
@@ -536,9 +536,15 @@ Error AudioStreamSample::save_to_wav(const String &p_path) {
int byte_pr_sample = 0;
switch (format) {
- case AudioStreamSample::FORMAT_8_BITS: byte_pr_sample = 1; break;
- case AudioStreamSample::FORMAT_16_BITS: byte_pr_sample = 2; break;
- case AudioStreamSample::FORMAT_IMA_ADPCM: byte_pr_sample = 4; break;
+ case AudioStreamSample::FORMAT_8_BITS:
+ byte_pr_sample = 1;
+ break;
+ case AudioStreamSample::FORMAT_16_BITS:
+ byte_pr_sample = 2;
+ break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM:
+ byte_pr_sample = 4;
+ break;
}
String file_path = p_path;
@@ -566,8 +572,8 @@ Error AudioStreamSample::save_to_wav(const String &p_path) {
file->store_32(sub_chunk_2_size); //Subchunk2Size
// Add data
- PoolVector<uint8_t> data = get_data();
- PoolVector<uint8_t>::Read read_data = data.read();
+ Vector<uint8_t> data = get_data();
+ const uint8_t *read_data = data.ptr();
switch (format) {
case AudioStreamSample::FORMAT_8_BITS:
for (unsigned int i = 0; i < data_bytes; i++) {
@@ -592,7 +598,6 @@ Error AudioStreamSample::save_to_wav(const String &p_path) {
}
Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() {
-
Ref<AudioStreamPlaybackSample> sample;
sample.instance();
sample->base = Ref<AudioStreamSample>(this);
@@ -600,12 +605,10 @@ Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() {
}
String AudioStreamSample::get_stream_name() const {
-
return "";
}
void AudioStreamSample::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamSample::set_data);
ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamSample::get_data);
@@ -629,7 +632,7 @@ void AudioStreamSample::_bind_methods() {
ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamSample::save_to_wav);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format");
ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong,Backward"), "set_loop_mode", "get_loop_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_begin"), "set_loop_begin", "get_loop_begin");
@@ -654,14 +657,14 @@ AudioStreamSample::AudioStreamSample() {
loop_begin = 0;
loop_end = 0;
mix_rate = 44100;
- data = NULL;
+ data = nullptr;
data_bytes = 0;
}
AudioStreamSample::~AudioStreamSample() {
if (data) {
- AudioServer::get_singleton()->audio_data_free(data);
- data = NULL;
+ memfree(data);
+ data = nullptr;
data_bytes = 0;
}
}
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index adcac14ea8..d91cdef57d 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -36,7 +36,6 @@
class AudioStreamSample;
class AudioStreamPlaybackSample : public AudioStreamPlayback {
-
GDCLASS(AudioStreamPlaybackSample, AudioStreamPlayback);
enum {
MIX_FRAC_BITS = 13,
@@ -45,7 +44,6 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback {
};
struct IMA_ADPCM_State {
-
int16_t step_index;
int32_t predictor;
/* values at loop point */
@@ -66,16 +64,16 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback {
void do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm);
public:
- virtual void start(float p_from_pos = 0.0);
- virtual void stop();
- virtual bool is_playing() const;
+ virtual void start(float p_from_pos = 0.0) override;
+ virtual void stop() override;
+ virtual bool is_playing() const override;
- virtual int get_loop_count() const; //times it looped
+ virtual int get_loop_count() const override; //times it looped
- virtual float get_playback_position() const;
- virtual void seek(float p_time);
+ virtual float get_playback_position() const override;
+ virtual void seek(float p_time) override;
- virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
+ virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override;
AudioStreamPlaybackSample();
};
@@ -136,15 +134,15 @@ public:
void set_stereo(bool p_enable);
bool is_stereo() const;
- virtual float get_length() const; //if supported, otherwise return 0
+ virtual float get_length() const override; //if supported, otherwise return 0
- void set_data(const PoolVector<uint8_t> &p_data);
- PoolVector<uint8_t> get_data() const;
+ void set_data(const Vector<uint8_t> &p_data);
+ Vector<uint8_t> get_data() const;
Error save_to_wav(const String &p_path);
- virtual Ref<AudioStreamPlayback> instance_playback();
- virtual String get_stream_name() const;
+ virtual Ref<AudioStreamPlayback> instance_playback() override;
+ virtual String get_stream_name() const override;
AudioStreamSample();
~AudioStreamSample();
diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp
index 06323a8d31..10f0de8ff8 100644
--- a/scene/resources/bit_map.cpp
+++ b/scene/resources/bit_map.cpp
@@ -33,7 +33,6 @@
#include "core/io/image_loader.h"
void BitMap::create(const Size2 &p_size) {
-
ERR_FAIL_COND(p_size.width < 1);
ERR_FAIL_COND(p_size.height < 1);
@@ -44,7 +43,6 @@ void BitMap::create(const Size2 &p_size) {
}
void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshold) {
-
ERR_FAIL_COND(p_image.is_null() || p_image->empty());
Ref<Image> img = p_image->duplicate();
img->convert(Image::FORMAT_LA8);
@@ -52,11 +50,10 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshol
create(Size2(img->get_width(), img->get_height()));
- PoolVector<uint8_t>::Read r = img->get_data().read();
+ const uint8_t *r = img->get_data().ptr();
uint8_t *w = bitmask.ptrw();
for (int i = 0; i < width * height; i++) {
-
int bbyte = i / 8;
int bbit = i % 8;
if (r[i * 2 + 1] / 255.0 > p_threshold) {
@@ -66,24 +63,22 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshol
}
void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) {
-
Rect2i current = Rect2i(0, 0, width, height).clip(p_rect);
uint8_t *data = bitmask.ptrw();
for (int i = current.position.x; i < current.position.x + current.size.x; i++) {
-
for (int j = current.position.y; j < current.position.y + current.size.y; j++) {
-
int ofs = width * j + i;
int bbyte = ofs / 8;
int bbit = ofs % 8;
uint8_t b = data[bbyte];
- if (p_value)
+ if (p_value) {
b |= (1 << bbit);
- else
+ } else {
b &= ~(1 << bbit);
+ }
data[bbyte] = b;
}
@@ -91,7 +86,6 @@ void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) {
}
int BitMap::get_true_bit_count() const {
-
int ds = bitmask.size();
const uint8_t *d = bitmask.ptr();
int c = 0;
@@ -99,7 +93,6 @@ int BitMap::get_true_bit_count() const {
//fast, almost branchless version
for (int i = 0; i < ds; i++) {
-
c += (d[i] & (1 << 7)) >> 7;
c += (d[i] & (1 << 6)) >> 6;
c += (d[i] & (1 << 5)) >> 5;
@@ -114,7 +107,6 @@ int BitMap::get_true_bit_count() const {
}
void BitMap::set_bit(const Point2 &p_pos, bool p_value) {
-
int x = p_pos.x;
int y = p_pos.y;
@@ -127,16 +119,16 @@ void BitMap::set_bit(const Point2 &p_pos, bool p_value) {
uint8_t b = bitmask[bbyte];
- if (p_value)
+ if (p_value) {
b |= (1 << bbit);
- else
+ } else {
b &= ~(1 << bbit);
+ }
bitmask.write[bbyte] = b;
}
bool BitMap::get_bit(const Point2 &p_pos) const {
-
int x = Math::fast_ftoi(p_pos.x);
int y = Math::fast_ftoi(p_pos.y);
ERR_FAIL_INDEX_V(x, width, false);
@@ -150,12 +142,10 @@ bool BitMap::get_bit(const Point2 &p_pos) const {
}
Size2 BitMap::get_size() const {
-
return Size2(width, height);
}
void BitMap::_set_data(const Dictionary &p_d) {
-
ERR_FAIL_COND(!p_d.has("size"));
ERR_FAIL_COND(!p_d.has("data"));
@@ -164,7 +154,6 @@ void BitMap::_set_data(const Dictionary &p_d) {
}
Dictionary BitMap::_get_data() const {
-
Dictionary d;
d["size"] = get_size();
d["data"] = bitmask;
@@ -172,7 +161,6 @@ Dictionary BitMap::_get_data() const {
}
Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) const {
-
int stepx = 0;
int stepy = 0;
int prevx = 0;
@@ -209,7 +197,6 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
}
switch (sv) {
-
case 1:
case 5:
case 13:
@@ -354,8 +341,9 @@ static float perpendicular_distance(const Vector2 &i, const Vector2 &start, cons
}
static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) {
- if (v.size() < 3)
+ if (v.size() < 3) {
return v;
+ }
int index = -1;
float dist = 0;
@@ -368,7 +356,6 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) {
}
}
if (dist > optimization) {
-
Vector<Vector2> left, right;
left.resize(index);
for (int i = 0; i < index; i++) {
@@ -424,9 +411,8 @@ struct FillBitsStackEntry {
};
static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) {
-
// Using a custom stack to work iteratively to avoid stack overflow on big bitmaps
- PoolVector<FillBitsStackEntry> stack;
+ Vector<FillBitsStackEntry> stack;
// Tracking size since we won't be shrinking the stack vector
int stack_size = 0;
@@ -453,15 +439,17 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_
continue;
}
- if (i < rect.position.x || i >= rect.position.x + rect.size.x)
+ if (i < rect.position.x || i >= rect.position.x + rect.size.x) {
continue;
- if (j < rect.position.y || j >= rect.position.y + rect.size.y)
+ }
+ if (j < rect.position.y || j >= rect.position.y + rect.size.y) {
continue;
+ }
- if (p_map->get_bit(Vector2(i, j)))
+ if (p_map->get_bit(Vector2(i, j))) {
continue;
- else if (p_src->get_bit(Vector2(i, j))) {
+ } else if (p_src->get_bit(Vector2(i, j))) {
p_map->set_bit(Vector2(i, j), true);
FillBitsStackEntry se = { pos, i, j };
@@ -493,8 +481,7 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_
print_verbose("BitMap: Max stack size: " + itos(stack.size()));
}
-Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const {
-
+Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const {
Rect2i r = Rect2i(0, 0, width, height).clip(p_rect);
print_verbose("BitMap: Rect: " + r);
@@ -503,11 +490,10 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl
fill.instance();
fill->create(get_size());
- Vector<Vector<Vector2> > polygons;
+ Vector<Vector<Vector2>> polygons;
for (int i = r.position.y; i < r.position.y + r.size.height; i++) {
for (int j = r.position.x; j < r.position.x + r.size.width; j++) {
if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) {
-
fill_bits(this, fill, Point2i(j, i), r);
Vector<Vector2> polygon = _march_square(r, Point2i(j, i));
@@ -529,7 +515,6 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl
}
void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {
-
if (p_pixels == 0) {
return;
}
@@ -546,35 +531,38 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {
for (int i = r.position.y; i < r.position.y + r.size.height; i++) {
for (int j = r.position.x; j < r.position.x + r.size.width; j++) {
- if (bit_value == get_bit(Point2(j, i)))
+ if (bit_value == get_bit(Point2(j, i))) {
continue;
+ }
bool found = false;
for (int y = i - p_pixels; y <= i + p_pixels; y++) {
for (int x = j - p_pixels; x <= j + p_pixels; x++) {
-
bool outside = false;
if ((x < p_rect.position.x) || (x >= p_rect.position.x + p_rect.size.x) || (y < p_rect.position.y) || (y >= p_rect.position.y + p_rect.size.y)) {
// outside of rectangle counts as bit not set
- if (!bit_value)
+ if (!bit_value) {
outside = true;
- else
+ } else {
continue;
+ }
}
float d = Point2(j, i).distance_to(Point2(x, y)) - CMP_EPSILON;
- if (d > p_pixels)
+ if (d > p_pixels) {
continue;
+ }
if (outside || (bit_value == copy->get_bit(Point2(x, y)))) {
found = true;
break;
}
}
- if (found)
+ if (found) {
break;
+ }
}
if (found) {
@@ -585,27 +573,24 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {
}
void BitMap::shrink_mask(int p_pixels, const Rect2 &p_rect) {
-
grow_mask(-p_pixels, p_rect);
}
Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const {
-
- Vector<Vector<Vector2> > result = clip_opaque_to_polygons(p_rect, p_epsilon);
+ Vector<Vector<Vector2>> result = clip_opaque_to_polygons(p_rect, p_epsilon);
// Convert result to bindable types
Array result_array;
result_array.resize(result.size());
for (int i = 0; i < result.size(); i++) {
-
const Vector<Vector2> &polygon = result[i];
- PoolVector2Array polygon_array;
+ PackedVector2Array polygon_array;
polygon_array.resize(polygon.size());
{
- PoolVector2Array::Write w = polygon_array.write();
+ Vector2 *w = polygon_array.ptrw();
for (int j = 0; j < polygon.size(); j++) {
w[j] = polygon[j];
}
@@ -618,7 +603,6 @@ Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) con
}
void BitMap::resize(const Size2 &p_new_size) {
-
Ref<BitMap> new_bitmap;
new_bitmap.instance();
new_bitmap->create(p_new_size);
@@ -636,23 +620,20 @@ void BitMap::resize(const Size2 &p_new_size) {
}
Ref<Image> BitMap::convert_to_image() const {
-
Ref<Image> image;
image.instance();
image->create(width, height, false, Image::FORMAT_L8);
- image->lock();
+
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
image->set_pixel(i, j, get_bit(Point2(i, j)) ? Color(1, 1, 1) : Color(0, 0, 0));
}
}
- image->unlock();
-
return image;
}
-void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
+void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
int x = p_pos.x;
int y = p_pos.y;
int w = p_bitmap->get_size().width;
@@ -662,10 +643,12 @@ void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
for (int j = 0; j < h; j++) {
int px = x + i;
int py = y + j;
- if (px < 0 || px >= width)
+ if (px < 0 || px >= width) {
continue;
- if (py < 0 || py >= height)
+ }
+ if (py < 0 || py >= height) {
continue;
+ }
if (p_bitmap->get_bit(Vector2(i, j))) {
set_bit(Vector2(x, y), true);
}
@@ -674,7 +657,6 @@ void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
}
void BitMap::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create);
ClassDB::bind_method(D_METHOD("create_from_image_alpha", "image", "threshold"), &BitMap::create_from_image_alpha, DEFVAL(0.1));
@@ -696,7 +678,6 @@ void BitMap::_bind_methods() {
}
BitMap::BitMap() {
-
width = 0;
height = 0;
}
diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h
index ed332dffa4..59f3b4dc3c 100644
--- a/scene/resources/bit_map.h
+++ b/scene/resources/bit_map.h
@@ -36,7 +36,6 @@
#include "core/resource.h"
class BitMap : public Resource {
-
GDCLASS(BitMap, Resource);
OBJ_SAVE_TYPE(BitMap);
@@ -72,7 +71,7 @@ public:
void blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap);
Ref<Image> convert_to_image() const;
- Vector<Vector<Vector2> > clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const;
+ Vector<Vector<Vector2>> clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const;
BitMap();
};
diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape_3d.cpp
index dee3943b8e..e1c8a377c0 100644
--- a/scene/resources/box_shape.cpp
+++ b/scene/resources/box_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* box_shape.cpp */
+/* box_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "box_shape.h"
-#include "servers/physics_server.h"
-
-Vector<Vector3> BoxShape::get_debug_mesh_lines() {
+#include "box_shape_3d.h"
+#include "servers/physics_server_3d.h"
+Vector<Vector3> BoxShape3D::get_debug_mesh_lines() const {
Vector<Vector3> lines;
AABB aabb;
aabb.position = -get_extents();
@@ -48,35 +47,34 @@ Vector<Vector3> BoxShape::get_debug_mesh_lines() {
return lines;
}
-void BoxShape::_update_shape() {
-
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), extents);
- Shape::_update_shape();
+real_t BoxShape3D::get_enclosing_radius() const {
+ return extents.length();
}
-void BoxShape::set_extents(const Vector3 &p_extents) {
+void BoxShape3D::_update_shape() {
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), extents);
+ Shape3D::_update_shape();
+}
+void BoxShape3D::set_extents(const Vector3 &p_extents) {
extents = p_extents;
_update_shape();
notify_change_to_owners();
_change_notify("extents");
}
-Vector3 BoxShape::get_extents() const {
-
+Vector3 BoxShape3D::get_extents() const {
return extents;
}
-void BoxShape::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BoxShape::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &BoxShape::get_extents);
+void BoxShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BoxShape3D::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &BoxShape3D::get_extents);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents");
}
-BoxShape::BoxShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) {
-
+BoxShape3D::BoxShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_BOX)) {
set_extents(Vector3(1, 1, 1));
}
diff --git a/scene/resources/box_shape.h b/scene/resources/box_shape_3d.h
index b577a70e1e..fe634ce568 100644
--- a/scene/resources/box_shape.h
+++ b/scene/resources/box_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* box_shape.h */
+/* box_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,25 +31,25 @@
#ifndef BOX_SHAPE_H
#define BOX_SHAPE_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class BoxShape : public Shape {
-
- GDCLASS(BoxShape, Shape);
+class BoxShape3D : public Shape3D {
+ GDCLASS(BoxShape3D, Shape3D);
Vector3 extents;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
void set_extents(const Vector3 &p_extents);
Vector3 get_extents() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- BoxShape();
+ BoxShape3D();
};
#endif // BOX_SHAPE_H
diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp
new file mode 100644
index 0000000000..6b6ed51ed0
--- /dev/null
+++ b/scene/resources/camera_effects.cpp
@@ -0,0 +1,197 @@
+/*************************************************************************/
+/* camera_effects.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "camera_effects.h"
+
+#include "servers/rendering_server.h"
+
+RID CameraEffects::get_rid() const {
+ return camera_effects;
+}
+
+// DOF blur
+
+void CameraEffects::set_dof_blur_far_enabled(bool p_enabled) {
+ dof_blur_far_enabled = p_enabled;
+ _update_dof_blur();
+ _change_notify();
+}
+
+bool CameraEffects::is_dof_blur_far_enabled() const {
+ return dof_blur_far_enabled;
+}
+
+void CameraEffects::set_dof_blur_far_distance(float p_distance) {
+ dof_blur_far_distance = p_distance;
+ _update_dof_blur();
+}
+
+float CameraEffects::get_dof_blur_far_distance() const {
+ return dof_blur_far_distance;
+}
+
+void CameraEffects::set_dof_blur_far_transition(float p_distance) {
+ dof_blur_far_transition = p_distance;
+ _update_dof_blur();
+}
+
+float CameraEffects::get_dof_blur_far_transition() const {
+ return dof_blur_far_transition;
+}
+
+void CameraEffects::set_dof_blur_near_enabled(bool p_enabled) {
+ dof_blur_near_enabled = p_enabled;
+ _update_dof_blur();
+ _change_notify();
+}
+
+bool CameraEffects::is_dof_blur_near_enabled() const {
+ return dof_blur_near_enabled;
+}
+
+void CameraEffects::set_dof_blur_near_distance(float p_distance) {
+ dof_blur_near_distance = p_distance;
+ _update_dof_blur();
+}
+
+float CameraEffects::get_dof_blur_near_distance() const {
+ return dof_blur_near_distance;
+}
+
+void CameraEffects::set_dof_blur_near_transition(float p_distance) {
+ dof_blur_near_transition = p_distance;
+ _update_dof_blur();
+}
+
+float CameraEffects::get_dof_blur_near_transition() const {
+ return dof_blur_near_transition;
+}
+
+void CameraEffects::set_dof_blur_amount(float p_amount) {
+ dof_blur_amount = p_amount;
+ _update_dof_blur();
+}
+
+float CameraEffects::get_dof_blur_amount() const {
+ return dof_blur_amount;
+}
+
+void CameraEffects::_update_dof_blur() {
+ RS::get_singleton()->camera_effects_set_dof_blur(
+ camera_effects,
+ dof_blur_far_enabled,
+ dof_blur_far_distance,
+ dof_blur_far_transition,
+ dof_blur_near_enabled,
+ dof_blur_near_distance,
+ dof_blur_near_transition,
+ dof_blur_amount);
+}
+
+// Custom exposure
+
+void CameraEffects::set_override_exposure_enabled(bool p_enabled) {
+ override_exposure_enabled = p_enabled;
+ _update_override_exposure();
+}
+
+bool CameraEffects::is_override_exposure_enabled() const {
+ return override_exposure_enabled;
+}
+
+void CameraEffects::set_override_exposure(float p_exposure) {
+ override_exposure = p_exposure;
+ _update_override_exposure();
+}
+
+float CameraEffects::get_override_exposure() const {
+ return override_exposure;
+}
+
+void CameraEffects::_update_override_exposure() {
+ RS::get_singleton()->camera_effects_set_custom_exposure(
+ camera_effects,
+ override_exposure_enabled,
+ override_exposure);
+}
+
+// Private methods, constructor and destructor
+
+void CameraEffects::_bind_methods() {
+ // DOF blur
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &CameraEffects::set_dof_blur_far_enabled);
+ ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &CameraEffects::is_dof_blur_far_enabled);
+ ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "distance"), &CameraEffects::set_dof_blur_far_distance);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &CameraEffects::get_dof_blur_far_distance);
+ ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "distance"), &CameraEffects::set_dof_blur_far_transition);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &CameraEffects::get_dof_blur_far_transition);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &CameraEffects::set_dof_blur_near_enabled);
+ ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &CameraEffects::is_dof_blur_near_enabled);
+ ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "distance"), &CameraEffects::set_dof_blur_near_distance);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &CameraEffects::get_dof_blur_near_distance);
+ ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "distance"), &CameraEffects::set_dof_blur_near_transition);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &CameraEffects::get_dof_blur_near_transition);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_amount", "amount"), &CameraEffects::set_dof_blur_amount);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_amount"), &CameraEffects::get_dof_blur_amount);
+
+ ADD_GROUP("DOF Blur", "dof_blur_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount");
+
+ // Override exposure
+
+ ClassDB::bind_method(D_METHOD("set_override_exposure_enabled", "enabled"), &CameraEffects::set_override_exposure_enabled);
+ ClassDB::bind_method(D_METHOD("is_override_exposure_enabled"), &CameraEffects::is_override_exposure_enabled);
+ ClassDB::bind_method(D_METHOD("set_override_exposure", "exposure"), &CameraEffects::set_override_exposure);
+ ClassDB::bind_method(D_METHOD("get_override_exposure"), &CameraEffects::get_override_exposure);
+
+ ADD_GROUP("Override Exposure", "override_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_exposure_enabled"), "set_override_exposure_enabled", "is_override_exposure_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "override_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_override_exposure", "get_override_exposure");
+}
+
+CameraEffects::CameraEffects() {
+ camera_effects = RS::get_singleton()->camera_effects_create();
+
+ _update_dof_blur();
+ _update_override_exposure();
+}
+
+CameraEffects::~CameraEffects() {
+ RS::get_singleton()->free(camera_effects);
+}
diff --git a/scene/resources/space_2d.h b/scene/resources/camera_effects.h
index ff88c40348..99fd4eb37c 100644
--- a/scene/resources/space_2d.h
+++ b/scene/resources/camera_effects.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* space_2d.h */
+/* camera_effects.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,29 +28,67 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SPACE_2D_H
-#define SPACE_2D_H
+#ifndef CAMERA_EFFECTS_H
+#define CAMERA_EFFECTS_H
#include "core/resource.h"
-#include "servers/physics_2d_server.h"
+#include "core/rid.h"
-class Space2D : public Resource {
+class CameraEffects : public Resource {
+ GDCLASS(CameraEffects, Resource);
- GDCLASS(Space2D, Resource);
- bool active;
- RID space;
+private:
+ RID camera_effects;
+
+ // DOF blur
+ bool dof_blur_far_enabled = false;
+ float dof_blur_far_distance = 10;
+ float dof_blur_far_transition = 5;
+
+ bool dof_blur_near_enabled = false;
+ float dof_blur_near_distance = 2;
+ float dof_blur_near_transition = 1;
+
+ float dof_blur_amount = 0.1;
+ void _update_dof_blur();
+
+ // Override exposure
+ bool override_exposure_enabled = false;
+ float override_exposure = 1.0;
+ void _update_override_exposure();
protected:
static void _bind_methods();
public:
- void set_active(bool p_active);
- bool is_active() const;
+ virtual RID get_rid() const override;
+
+ // DOF blur
+ void set_dof_blur_far_enabled(bool p_enabled);
+ bool is_dof_blur_far_enabled() const;
+ void set_dof_blur_far_distance(float p_distance);
+ float get_dof_blur_far_distance() const;
+ void set_dof_blur_far_transition(float p_distance);
+ float get_dof_blur_far_transition() const;
+
+ void set_dof_blur_near_enabled(bool p_enabled);
+ bool is_dof_blur_near_enabled() const;
+ void set_dof_blur_near_distance(float p_distance);
+ float get_dof_blur_near_distance() const;
+ void set_dof_blur_near_transition(float p_distance);
+ float get_dof_blur_near_transition() const;
+
+ void set_dof_blur_amount(float p_amount);
+ float get_dof_blur_amount() const;
- virtual RID get_rid() const;
+ // Override exposure
+ void set_override_exposure_enabled(bool p_enabled);
+ bool is_override_exposure_enabled() const;
+ void set_override_exposure(float p_exposure);
+ float get_override_exposure() const;
- Space2D();
- ~Space2D();
+ CameraEffects();
+ ~CameraEffects();
};
-#endif // SPACE_2D_H
+#endif // CAMERA_EFFECTS_H
diff --git a/scene/resources/canvas.cpp b/scene/resources/canvas.cpp
deleted file mode 100644
index 1dbd02ea28..0000000000
--- a/scene/resources/canvas.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*************************************************************************/
-/* canvas.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "canvas.h"
-#include "servers/visual_server.h"
-
-RID Canvas::get_rid() const {
-
- return canvas;
-}
-
-Canvas::Canvas() {
-
- canvas = VisualServer::get_singleton()->canvas_create();
-}
-
-Canvas::~Canvas() {
- VisualServer::get_singleton()->free(canvas);
-}
diff --git a/scene/resources/canvas.h b/scene/resources/canvas.h
deleted file mode 100644
index 621911fe0a..0000000000
--- a/scene/resources/canvas.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* canvas.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef CANVAS_H
-#define CANVAS_H
-
-#include "core/resource.h"
-
-class Canvas : public Resource {
-
- GDCLASS(Canvas, Resource);
-
- RID canvas;
-
-public:
- virtual RID get_rid() const;
- Canvas();
- ~Canvas();
-};
-
-#endif // CANVAS_H
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index 008e8bb13d..e519970f38 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -30,66 +30,63 @@
#include "capsule_shape_2d.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "core/math/geometry_2d.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
Vector<Vector2> CapsuleShape2D::_get_points() const {
-
Vector<Vector2> points;
for (int i = 0; i < 24; i++) {
Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5);
points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs);
- if (i == 6 || i == 18)
+ if (i == 6 || i == 18) {
points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs);
+ }
}
return points;
}
bool CapsuleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- return Geometry::is_point_in_polygon(p_point, _get_points());
+ return Geometry2D::is_point_in_polygon(p_point, _get_points());
}
void CapsuleShape2D::_update_shape() {
-
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), Vector2(radius, height));
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), Vector2(radius, height));
emit_changed();
}
void CapsuleShape2D::set_radius(real_t p_radius) {
-
radius = p_radius;
_update_shape();
}
real_t CapsuleShape2D::get_radius() const {
-
return radius;
}
void CapsuleShape2D::set_height(real_t p_height) {
-
height = p_height;
+ if (height < 0) {
+ height = 0;
+ }
+
_update_shape();
}
real_t CapsuleShape2D::get_height() const {
-
return height;
}
void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
Vector<Vector2> points = _get_points();
Vector<Color> col;
col.push_back(p_color);
- VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
+ RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}
Rect2 CapsuleShape2D::get_rect() const {
-
Vector2 he = Point2(get_radius(), get_radius() + get_height() * 0.5);
Rect2 rect;
rect.position = -he;
@@ -97,21 +94,23 @@ Rect2 CapsuleShape2D::get_rect() const {
return rect;
}
-void CapsuleShape2D::_bind_methods() {
+real_t CapsuleShape2D::get_enclosing_radius() const {
+ return radius + height * 0.5;
+}
+void CapsuleShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape2D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape2D::get_radius);
ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape2D::set_height);
ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape2D::get_height);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height"), "set_height", "get_height");
}
CapsuleShape2D::CapsuleShape2D() :
- Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) {
-
+ Shape2D(PhysicsServer2D::get_singleton()->capsule_shape_create()) {
radius = 10;
height = 20;
_update_shape();
diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h
index 8398fab839..1caa6c68b8 100644
--- a/scene/resources/capsule_shape_2d.h
+++ b/scene/resources/capsule_shape_2d.h
@@ -46,7 +46,7 @@ protected:
static void _bind_methods();
public:
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
void set_height(real_t p_height);
real_t get_height() const;
@@ -54,8 +54,9 @@ public:
void set_radius(real_t p_radius);
real_t get_radius() const;
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
CapsuleShape2D();
};
diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape_3d.cpp
index 61331a336d..9d1355eec6 100644
--- a/scene/resources/capsule_shape.cpp
+++ b/scene/resources/capsule_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* capsule_shape.cpp */
+/* capsule_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,96 +28,90 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "capsule_shape.h"
-#include "servers/physics_server.h"
-
-Vector<Vector3> CapsuleShape::get_debug_mesh_lines() {
+#include "capsule_shape_3d.h"
+#include "servers/physics_server_3d.h"
+Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() const {
float radius = get_radius();
float height = get_height();
Vector<Vector3> points;
- Vector3 d(0, 0, height * 0.5);
+ Vector3 d(0, height * 0.5, 0);
for (int i = 0; i < 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
- points.push_back(Vector3(a.x, a.y, 0) + d);
- points.push_back(Vector3(b.x, b.y, 0) + d);
+ points.push_back(Vector3(a.x, 0, a.y) + d);
+ points.push_back(Vector3(b.x, 0, b.y) + d);
- points.push_back(Vector3(a.x, a.y, 0) - d);
- points.push_back(Vector3(b.x, b.y, 0) - d);
+ points.push_back(Vector3(a.x, 0, a.y) - d);
+ points.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 90 == 0) {
-
- points.push_back(Vector3(a.x, a.y, 0) + d);
- points.push_back(Vector3(a.x, a.y, 0) - d);
+ points.push_back(Vector3(a.x, 0, a.y) + d);
+ points.push_back(Vector3(a.x, 0, a.y) - d);
}
Vector3 dud = i < 180 ? d : -d;
- points.push_back(Vector3(0, a.y, a.x) + dud);
- points.push_back(Vector3(0, b.y, b.x) + dud);
- points.push_back(Vector3(a.y, 0, a.x) + dud);
- points.push_back(Vector3(b.y, 0, b.x) + dud);
+ points.push_back(Vector3(0, a.x, a.y) + dud);
+ points.push_back(Vector3(0, b.x, b.y) + dud);
+ points.push_back(Vector3(a.y, a.x, 0) + dud);
+ points.push_back(Vector3(b.y, b.x, 0) + dud);
}
return points;
}
-void CapsuleShape::_update_shape() {
+real_t CapsuleShape3D::get_enclosing_radius() const {
+ return radius + height * 0.5;
+}
+void CapsuleShape3D::_update_shape() {
Dictionary d;
d["radius"] = radius;
d["height"] = height;
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), d);
- Shape::_update_shape();
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);
+ Shape3D::_update_shape();
}
-void CapsuleShape::set_radius(float p_radius) {
-
+void CapsuleShape3D::set_radius(float p_radius) {
radius = p_radius;
_update_shape();
notify_change_to_owners();
_change_notify("radius");
}
-float CapsuleShape::get_radius() const {
-
+float CapsuleShape3D::get_radius() const {
return radius;
}
-void CapsuleShape::set_height(float p_height) {
-
+void CapsuleShape3D::set_height(float p_height) {
height = p_height;
_update_shape();
notify_change_to_owners();
_change_notify("height");
}
-float CapsuleShape::get_height() const {
-
+float CapsuleShape3D::get_height() const {
return height;
}
-void CapsuleShape::_bind_methods() {
+void CapsuleShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape3D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape3D::get_radius);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape3D::set_height);
+ ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape3D::get_height);
- ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape::set_radius);
- ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape::get_radius);
- ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape::set_height);
- ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape::get_height);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height");
}
-CapsuleShape::CapsuleShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) {
-
+CapsuleShape3D::CapsuleShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CAPSULE)) {
radius = 1.0;
height = 1.0;
_update_shape();
diff --git a/scene/resources/capsule_shape.h b/scene/resources/capsule_shape_3d.h
index 8e7d7bcb94..432ca5654e 100644
--- a/scene/resources/capsule_shape.h
+++ b/scene/resources/capsule_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* capsule_shape.h */
+/* capsule_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,18 +31,17 @@
#ifndef CAPSULE_SHAPE_H
#define CAPSULE_SHAPE_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class CapsuleShape : public Shape {
-
- GDCLASS(CapsuleShape, Shape);
+class CapsuleShape3D : public Shape3D {
+ GDCLASS(CapsuleShape3D, Shape3D);
float radius;
float height;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
void set_radius(float p_radius);
@@ -50,9 +49,10 @@ public:
void set_height(float p_height);
float get_height() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- CapsuleShape();
+ CapsuleShape3D();
};
#endif // CAPSULE_SHAPE_H
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index 7142309e28..dc1bf3b185 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -30,37 +30,32 @@
#include "circle_shape_2d.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
bool CircleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return p_point.length() < get_radius() + p_tolerance;
}
void CircleShape2D::_update_shape() {
-
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), radius);
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), radius);
emit_changed();
}
void CircleShape2D::set_radius(real_t p_radius) {
-
radius = p_radius;
_update_shape();
}
real_t CircleShape2D::get_radius() const {
-
return radius;
}
void CircleShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CircleShape2D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &CircleShape2D::get_radius);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.01,16384,0.5"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,16384,0.5"), "set_radius", "get_radius");
}
Rect2 CircleShape2D::get_rect() const {
@@ -70,22 +65,23 @@ Rect2 CircleShape2D::get_rect() const {
return rect;
}
-void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
+real_t CircleShape2D::get_enclosing_radius() const {
+ return radius;
+}
+void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Vector<Vector2> points;
for (int i = 0; i < 24; i++) {
-
points.push_back(Vector2(Math::cos(i * Math_PI * 2 / 24.0), Math::sin(i * Math_PI * 2 / 24.0)) * get_radius());
}
Vector<Color> col;
col.push_back(p_color);
- VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
+ RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}
CircleShape2D::CircleShape2D() :
- Shape2D(Physics2DServer::get_singleton()->circle_shape_create()) {
-
+ Shape2D(PhysicsServer2D::get_singleton()->circle_shape_create()) {
radius = 10;
_update_shape();
}
diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h
index cafd291f13..ac8757e781 100644
--- a/scene/resources/circle_shape_2d.h
+++ b/scene/resources/circle_shape_2d.h
@@ -43,13 +43,14 @@ protected:
static void _bind_methods();
public:
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
void set_radius(real_t p_radius);
real_t get_radius() const;
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
CircleShape2D();
};
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index 640f395158..eecf8afa8f 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -30,80 +30,90 @@
#include "concave_polygon_shape_2d.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "core/math/geometry_2d.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
bool ConcavePolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- PoolVector<Vector2> s = get_segments();
+ Vector<Vector2> s = get_segments();
int len = s.size();
- if (len == 0 || (len % 2) == 1)
+ if (len == 0 || (len % 2) == 1) {
return false;
+ }
- PoolVector<Vector2>::Read r = s.read();
+ const Vector2 *r = s.ptr();
for (int i = 0; i < len; i += 2) {
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, &r[i]);
- if (p_point.distance_to(closest) < p_tolerance)
+ Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, &r[i]);
+ if (p_point.distance_to(closest) < p_tolerance) {
return true;
+ }
}
return false;
}
-void ConcavePolygonShape2D::set_segments(const PoolVector<Vector2> &p_segments) {
-
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), p_segments);
+void ConcavePolygonShape2D::set_segments(const Vector<Vector2> &p_segments) {
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), p_segments);
emit_changed();
}
-PoolVector<Vector2> ConcavePolygonShape2D::get_segments() const {
-
- return Physics2DServer::get_singleton()->shape_get_data(get_rid());
+Vector<Vector2> ConcavePolygonShape2D::get_segments() const {
+ return PhysicsServer2D::get_singleton()->shape_get_data(get_rid());
}
void ConcavePolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
- PoolVector<Vector2> s = get_segments();
+ Vector<Vector2> s = get_segments();
int len = s.size();
- if (len == 0 || (len % 2) == 1)
+ if (len == 0 || (len % 2) == 1) {
return;
+ }
- PoolVector<Vector2>::Read r = s.read();
+ const Vector2 *r = s.ptr();
for (int i = 0; i < len; i += 2) {
- VisualServer::get_singleton()->canvas_item_add_line(p_to_rid, r[i], r[i + 1], p_color, 2);
+ RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, r[i], r[i + 1], p_color, 2);
}
}
Rect2 ConcavePolygonShape2D::get_rect() const {
-
- PoolVector<Vector2> s = get_segments();
+ Vector<Vector2> s = get_segments();
int len = s.size();
- if (len == 0)
+ if (len == 0) {
return Rect2();
+ }
Rect2 rect;
- PoolVector<Vector2>::Read r = s.read();
+ const Vector2 *r = s.ptr();
for (int i = 0; i < len; i++) {
- if (i == 0)
+ if (i == 0) {
rect.position = r[i];
- else
+ } else {
rect.expand_to(r[i]);
+ }
}
return rect;
}
-void ConcavePolygonShape2D::_bind_methods() {
+real_t ConcavePolygonShape2D::get_enclosing_radius() const {
+ Vector<Vector2> data = get_segments();
+ const Vector2 *read = data.ptr();
+ real_t r = 0;
+ for (int i(0); i < data.size(); i++) {
+ r = MAX(read[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
+}
+void ConcavePolygonShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_segments", "segments"), &ConcavePolygonShape2D::set_segments);
ClassDB::bind_method(D_METHOD("get_segments"), &ConcavePolygonShape2D::get_segments);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "segments"), "set_segments", "get_segments");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "segments"), "set_segments", "get_segments");
}
ConcavePolygonShape2D::ConcavePolygonShape2D() :
- Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) {
- PoolVector<Vector2> empty;
+ Shape2D(PhysicsServer2D::get_singleton()->concave_polygon_shape_create()) {
+ Vector<Vector2> empty;
set_segments(empty);
}
diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h
index b95ed100e7..df8cc9920f 100644
--- a/scene/resources/concave_polygon_shape_2d.h
+++ b/scene/resources/concave_polygon_shape_2d.h
@@ -40,13 +40,14 @@ protected:
static void _bind_methods();
public:
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
- void set_segments(const PoolVector<Vector2> &p_segments);
- PoolVector<Vector2> get_segments() const;
+ void set_segments(const Vector<Vector2> &p_segments);
+ Vector<Vector2> get_segments() const;
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
ConcavePolygonShape2D();
};
diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape_3d.cpp
index 48cc08eae4..7cbafcbc4d 100644
--- a/scene/resources/concave_polygon_shape.cpp
+++ b/scene/resources/concave_polygon_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* concave_polygon_shape.cpp */
+/* concave_polygon_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,24 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "concave_polygon_shape.h"
+#include "concave_polygon_shape_3d.h"
-#include "servers/physics_server.h"
-
-Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() {
+#include "servers/physics_server_3d.h"
+Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() const {
Set<DrawEdge> edges;
- PoolVector<Vector3> data = get_faces();
+ Vector<Vector3> data = get_faces();
int datalen = data.size();
ERR_FAIL_COND_V((datalen % 3) != 0, Vector<Vector3>());
- PoolVector<Vector3>::Read r = data.read();
+ const Vector3 *r = data.ptr();
for (int i = 0; i < datalen; i += 3) {
-
for (int j = 0; j < 3; j++) {
-
DrawEdge de(r[i + j], r[i + ((j + 1) % 3)]);
edges.insert(de);
}
@@ -55,7 +52,6 @@ Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() {
points.resize(edges.size() * 2);
int idx = 0;
for (Set<DrawEdge>::Element *E = edges.front(); E; E = E->next()) {
-
points.write[idx + 0] = E->get().a;
points.write[idx + 1] = E->get().b;
idx += 2;
@@ -64,30 +60,36 @@ Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() {
return points;
}
-void ConcavePolygonShape::_update_shape() {
- Shape::_update_shape();
+real_t ConcavePolygonShape3D::get_enclosing_radius() const {
+ Vector<Vector3> data = get_faces();
+ const Vector3 *read = data.ptr();
+ real_t r = 0;
+ for (int i(0); i < data.size(); i++) {
+ r = MAX(read[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
}
-void ConcavePolygonShape::set_faces(const PoolVector<Vector3> &p_faces) {
+void ConcavePolygonShape3D::_update_shape() {
+ Shape3D::_update_shape();
+}
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), p_faces);
+void ConcavePolygonShape3D::set_faces(const Vector<Vector3> &p_faces) {
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), p_faces);
notify_change_to_owners();
}
-PoolVector<Vector3> ConcavePolygonShape::get_faces() const {
-
- return PhysicsServer::get_singleton()->shape_get_data(get_shape());
+Vector<Vector3> ConcavePolygonShape3D::get_faces() const {
+ return PhysicsServer3D::get_singleton()->shape_get_data(get_shape());
}
-void ConcavePolygonShape::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_faces", "faces"), &ConcavePolygonShape::set_faces);
- ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape::get_faces);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces");
+void ConcavePolygonShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_faces", "faces"), &ConcavePolygonShape3D::set_faces);
+ ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape3D::get_faces);
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces");
}
-ConcavePolygonShape::ConcavePolygonShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) {
-
+ConcavePolygonShape3D::ConcavePolygonShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONCAVE_POLYGON)) {
//set_planes(Vector3(1,1,1));
}
diff --git a/scene/resources/concave_polygon_shape.h b/scene/resources/concave_polygon_shape_3d.h
index 5e371954d4..c17765b9ef 100644
--- a/scene/resources/concave_polygon_shape.h
+++ b/scene/resources/concave_polygon_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* concave_polygon_shape.h */
+/* concave_polygon_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,24 +28,23 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CONCAVE_POLYGON_SHAPE_H
-#define CONCAVE_POLYGON_SHAPE_H
+#ifndef CONCAVE_POLYGON_SHAPE_3D_H
+#define CONCAVE_POLYGON_SHAPE_3D_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class ConcavePolygonShape : public Shape {
-
- GDCLASS(ConcavePolygonShape, Shape);
+class ConcavePolygonShape3D : public Shape3D {
+ GDCLASS(ConcavePolygonShape3D, Shape3D);
struct DrawEdge {
-
Vector3 a;
Vector3 b;
bool operator<(const DrawEdge &p_edge) const {
- if (a == p_edge.a)
+ if (a == p_edge.a) {
return b < p_edge.b;
- else
+ } else {
return a < p_edge.a;
+ }
}
DrawEdge(const Vector3 &p_a = Vector3(), const Vector3 &p_b = Vector3()) {
@@ -60,15 +59,16 @@ class ConcavePolygonShape : public Shape {
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
- void set_faces(const PoolVector<Vector3> &p_faces);
- PoolVector<Vector3> get_faces() const;
+ void set_faces(const Vector<Vector3> &p_faces);
+ Vector<Vector3> get_faces() const;
- Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- ConcavePolygonShape();
+ ConcavePolygonShape3D();
};
#endif // CONCAVE_POLYGON_SHAPE_H
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index c404190398..2b7531c630 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -30,73 +30,74 @@
#include "convex_polygon_shape_2d.h"
-#include "core/math/geometry.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "core/math/geometry_2d.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- return Geometry::is_point_in_polygon(p_point, points);
+ return Geometry2D::is_point_in_polygon(p_point, points);
}
void ConvexPolygonShape2D::_update_shape() {
-
Vector<Vector2> final_points = points;
- if (Geometry::is_polygon_clockwise(final_points)) { //needs to be counter clockwise
+ if (Geometry2D::is_polygon_clockwise(final_points)) { //needs to be counter clockwise
final_points.invert();
}
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), final_points);
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), final_points);
emit_changed();
}
void ConvexPolygonShape2D::set_point_cloud(const Vector<Vector2> &p_points) {
-
- Vector<Point2> hull = Geometry::convex_hull_2d(p_points);
+ Vector<Point2> hull = Geometry2D::convex_hull(p_points);
ERR_FAIL_COND(hull.size() < 3);
set_points(hull);
}
void ConvexPolygonShape2D::set_points(const Vector<Vector2> &p_points) {
-
points = p_points;
_update_shape();
}
Vector<Vector2> ConvexPolygonShape2D::get_points() const {
-
return points;
}
void ConvexPolygonShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_point_cloud", "point_cloud"), &ConvexPolygonShape2D::set_point_cloud);
ClassDB::bind_method(D_METHOD("set_points", "points"), &ConvexPolygonShape2D::set_points);
ClassDB::bind_method(D_METHOD("get_points"), &ConvexPolygonShape2D::get_points);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "points"), "set_points", "get_points");
}
void ConvexPolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
Vector<Color> col;
col.push_back(p_color);
- VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
+ RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}
Rect2 ConvexPolygonShape2D::get_rect() const {
-
Rect2 rect;
for (int i = 0; i < points.size(); i++) {
- if (i == 0)
+ if (i == 0) {
rect.position = points[i];
- else
+ } else {
rect.expand_to(points[i]);
+ }
}
return rect;
}
+real_t ConvexPolygonShape2D::get_enclosing_radius() const {
+ real_t r = 0;
+ for (int i(0); i < get_points().size(); i++) {
+ r = MAX(get_points()[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
+}
+
ConvexPolygonShape2D::ConvexPolygonShape2D() :
- Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) {
+ Shape2D(PhysicsServer2D::get_singleton()->convex_polygon_shape_create()) {
}
diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h
index ed6be738ab..294157bec5 100644
--- a/scene/resources/convex_polygon_shape_2d.h
+++ b/scene/resources/convex_polygon_shape_2d.h
@@ -43,14 +43,15 @@ protected:
static void _bind_methods();
public:
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
void set_point_cloud(const Vector<Vector2> &p_points);
void set_points(const Vector<Vector2> &p_points);
Vector<Vector2> get_points() const;
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
ConvexPolygonShape2D();
};
diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape_3d.cpp
index 1498eb4af9..29549e1114 100644
--- a/scene/resources/convex_polygon_shape.cpp
+++ b/scene/resources/convex_polygon_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* convex_polygon_shape.cpp */
+/* convex_polygon_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,18 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "convex_polygon_shape.h"
+#include "convex_polygon_shape_3d.h"
#include "core/math/quick_hull.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
-Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() {
-
- PoolVector<Vector3> points = get_points();
+Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const {
+ Vector<Vector3> points = get_points();
if (points.size() > 3) {
-
Vector<Vector3> varr = Variant(points);
- Geometry::MeshData md;
+ Geometry3D::MeshData md;
Error err = QuickHull::build(varr, md);
if (err == OK) {
Vector<Vector3> lines;
@@ -55,32 +53,38 @@ Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() {
return Vector<Vector3>();
}
-void ConvexPolygonShape::_update_shape() {
-
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), points);
- Shape::_update_shape();
+real_t ConvexPolygonShape3D::get_enclosing_radius() const {
+ Vector<Vector3> data = get_points();
+ const Vector3 *read = data.ptr();
+ real_t r = 0;
+ for (int i(0); i < data.size(); i++) {
+ r = MAX(read[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
}
-void ConvexPolygonShape::set_points(const PoolVector<Vector3> &p_points) {
+void ConvexPolygonShape3D::_update_shape() {
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), points);
+ Shape3D::_update_shape();
+}
+void ConvexPolygonShape3D::set_points(const Vector<Vector3> &p_points) {
points = p_points;
_update_shape();
notify_change_to_owners();
}
-PoolVector<Vector3> ConvexPolygonShape::get_points() const {
-
+Vector<Vector3> ConvexPolygonShape3D::get_points() const {
return points;
}
-void ConvexPolygonShape::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_points", "points"), &ConvexPolygonShape::set_points);
- ClassDB::bind_method(D_METHOD("get_points"), &ConvexPolygonShape::get_points);
+void ConvexPolygonShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_points", "points"), &ConvexPolygonShape3D::set_points);
+ ClassDB::bind_method(D_METHOD("get_points"), &ConvexPolygonShape3D::get_points);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "points"), "set_points", "get_points");
}
-ConvexPolygonShape::ConvexPolygonShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) {
+ConvexPolygonShape3D::ConvexPolygonShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONVEX_POLYGON)) {
}
diff --git a/scene/resources/convex_polygon_shape.h b/scene/resources/convex_polygon_shape_3d.h
index 4725d09b26..f436d2f5d4 100644
--- a/scene/resources/convex_polygon_shape.h
+++ b/scene/resources/convex_polygon_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* convex_polygon_shape.h */
+/* convex_polygon_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,25 +31,25 @@
#ifndef CONVEX_POLYGON_SHAPE_H
#define CONVEX_POLYGON_SHAPE_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class ConvexPolygonShape : public Shape {
-
- GDCLASS(ConvexPolygonShape, Shape);
- PoolVector<Vector3> points;
+class ConvexPolygonShape3D : public Shape3D {
+ GDCLASS(ConvexPolygonShape3D, Shape3D);
+ Vector<Vector3> points;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
- void set_points(const PoolVector<Vector3> &p_points);
- PoolVector<Vector3> get_points() const;
+ void set_points(const Vector<Vector3> &p_points);
+ Vector<Vector3> get_points() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- ConvexPolygonShape();
+ ConvexPolygonShape3D();
};
#endif // CONVEX_POLYGON_SHAPE_H
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 397f6ca906..de076670cf 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -58,10 +58,11 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
// Add a point and preserve order
// Curve bounds is in 0..1
- if (p_pos.x > MAX_X)
+ if (p_pos.x > MAX_X) {
p_pos.x = MAX_X;
- else if (p_pos.x < MIN_X)
+ } else if (p_pos.x < MIN_X) {
p_pos.x = MIN_X;
+ }
int ret = -1;
@@ -83,7 +84,6 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
}
} else {
-
int i = get_index(p_pos.x);
if (i == 0 && p_pos.x < _points[0].pos.x) {
@@ -106,7 +106,6 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
}
int Curve::get_index(real_t offset) const {
-
// Lower-bound float binary search
int imin = 0;
@@ -130,13 +129,13 @@ int Curve::get_index(real_t offset) const {
}
// Will happen if the offset is out of bounds
- if (offset > _points[imax].pos.x)
+ if (offset > _points[imax].pos.x) {
return imax;
+ }
return imin;
}
void Curve::clean_dupes() {
-
bool dirty = false;
for (int i = 1; i < _points.size(); ++i) {
@@ -148,8 +147,9 @@ void Curve::clean_dupes() {
}
}
- if (dirty)
+ if (dirty) {
mark_dirty();
+ }
}
void Curve::set_point_left_tangent(int i, real_t tangent) {
@@ -237,8 +237,9 @@ int Curve::set_point_offset(int p_index, float offset) {
_points.write[i].right_tangent = p.right_tangent;
_points.write[i].left_mode = p.left_mode;
_points.write[i].right_mode = p.right_mode;
- if (p_index != i)
+ if (p_index != i) {
update_auto_tangents(p_index);
+ }
update_auto_tangents(i);
return i;
}
@@ -254,7 +255,6 @@ Curve::Point Curve::get_point(int p_index) const {
}
void Curve::update_auto_tangents(int i) {
-
Point &p = _points.write[i];
if (i > 0) {
@@ -305,26 +305,29 @@ void Curve::set_max_value(float p_max) {
}
real_t Curve::interpolate(real_t offset) const {
- if (_points.size() == 0)
+ if (_points.size() == 0) {
return 0;
- if (_points.size() == 1)
+ }
+ if (_points.size() == 1) {
return _points[0].pos.y;
+ }
int i = get_index(offset);
- if (i == _points.size() - 1)
+ if (i == _points.size() - 1) {
return _points[i].pos.y;
+ }
real_t local = offset - _points[i].pos.x;
- if (i == 0 && local <= 0)
+ if (i == 0 && local <= 0) {
return _points[0].pos.y;
+ }
return interpolate_local_nocheck(i, local);
}
real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
-
const Point a = _points[index];
const Point b = _points[index + 1];
@@ -344,8 +347,9 @@ real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
// Control points are chosen at equal distances
real_t d = b.pos.x - a.pos.x;
- if (Math::abs(d) <= CMP_EPSILON)
+ if (Math::abs(d) <= CMP_EPSILON) {
return b.pos.y;
+ }
local_offset /= d;
d /= 3.0;
real_t yac = a.pos.y + d * a.right_tangent;
@@ -362,13 +366,11 @@ void Curve::mark_dirty() {
}
Array Curve::get_data() const {
-
Array output;
const unsigned int ELEMS = 5;
output.resize(_points.size() * ELEMS);
for (int j = 0; j < _points.size(); ++j) {
-
const Point p = _points[j];
int i = j * ELEMS;
@@ -392,7 +394,7 @@ void Curve::set_data(Array input) {
for (int i = 0; i < input.size(); i += ELEMS) {
ERR_FAIL_COND(input[i].get_type() != Variant::VECTOR2);
ERR_FAIL_COND(!input[i + 1].is_num());
- ERR_FAIL_COND(input[i + 2].get_type() != Variant::REAL);
+ ERR_FAIL_COND(input[i + 2].get_type() != Variant::FLOAT);
ERR_FAIL_COND(input[i + 3].get_type() != Variant::INT);
int left_mode = input[i + 3];
@@ -406,7 +408,6 @@ void Curve::set_data(Array input) {
_points.resize(input.size() / ELEMS);
for (int j = 0; j < _points.size(); ++j) {
-
Point &p = _points.write[j];
int i = j * ELEMS;
@@ -457,8 +458,9 @@ real_t Curve::interpolate_baked(real_t offset) {
// Special cases if the cache is too small
if (_baked_cache.size() == 0) {
- if (_points.size() == 0)
+ if (_points.size() == 0) {
return 0;
+ }
return _points[0].pos.y;
} else if (_baked_cache.size() == 1) {
return _baked_cache[0];
@@ -486,7 +488,6 @@ real_t Curve::interpolate_baked(real_t offset) {
void Curve::ensure_default_setup(float p_min, float p_max) {
if (_points.size() == 0 && _min_value == 0 && _max_value == 1) {
-
add_point(Vector2(0, 1));
add_point(Vector2(1, 1));
set_min_value(p_min);
@@ -495,7 +496,6 @@ void Curve::ensure_default_setup(float p_min, float p_max) {
}
void Curve::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve::get_point_count);
ClassDB::bind_method(D_METHOD("add_point", "position", "left_tangent", "right_tangent", "left_mode", "right_mode"), &Curve::add_point, DEFVAL(0), DEFVAL(0), DEFVAL(TANGENT_FREE), DEFVAL(TANGENT_FREE));
ClassDB::bind_method(D_METHOD("remove_point", "index"), &Curve::remove_point);
@@ -524,8 +524,8 @@ void Curve::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_data"), &Curve::get_data);
ClassDB::bind_method(D_METHOD("_set_data", "data"), &Curve::set_data);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_min_value", "get_min_value");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_max_value", "get_max_value");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_min_value", "get_min_value");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_max_value", "get_max_value");
ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_resolution", PROPERTY_HINT_RANGE, "1,1000,1"), "set_bake_resolution", "get_bake_resolution");
ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
@@ -537,54 +537,51 @@ void Curve::_bind_methods() {
}
int Curve2D::get_point_count() const {
-
return points.size();
}
-void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
+void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
Point n;
n.pos = p_pos;
n.in = p_in;
n.out = p_out;
- if (p_atpos >= 0 && p_atpos < points.size())
+ if (p_atpos >= 0 && p_atpos < points.size()) {
points.insert(p_atpos, n);
- else
+ } else {
points.push_back(n);
+ }
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
void Curve2D::set_point_position(int p_index, const Vector2 &p_pos) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].pos = p_pos;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector2 Curve2D::get_point_position(int p_index) const {
+Vector2 Curve2D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
return points[p_index].pos;
}
void Curve2D::set_point_in(int p_index, const Vector2 &p_in) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].in = p_in;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector2 Curve2D::get_point_in(int p_index) const {
+Vector2 Curve2D::get_point_in(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
return points[p_index].in;
}
void Curve2D::set_point_out(int p_index, const Vector2 &p_out) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].out = p_out;
@@ -593,13 +590,11 @@ void Curve2D::set_point_out(int p_index, const Vector2 &p_out) {
}
Vector2 Curve2D::get_point_out(int p_index) const {
-
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
return points[p_index].out;
}
void Curve2D::remove_point(int p_index) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.remove(p_index);
baked_cache_dirty = true;
@@ -615,14 +610,14 @@ void Curve2D::clear_points() {
}
Vector2 Curve2D::interpolate(int p_index, float p_offset) const {
-
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector2());
- if (p_index >= pc - 1)
+ if (p_index >= pc - 1) {
return points[pc - 1].pos;
- else if (p_index < 0)
+ } else if (p_index < 0) {
return points[0].pos;
+ }
Vector2 p0 = points[p_index].pos;
Vector2 p1 = p0 + points[p_index].out;
@@ -633,17 +628,16 @@ Vector2 Curve2D::interpolate(int p_index, float p_offset) const {
}
Vector2 Curve2D::interpolatef(real_t p_findex) const {
-
- if (p_findex < 0)
+ if (p_findex < 0) {
p_findex = 0;
- else if (p_findex >= points.size())
+ } else if (p_findex >= points.size()) {
p_findex = points.size();
+ }
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const {
-
float mp = p_begin + (p_end - p_begin) * 0.5;
Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
@@ -654,7 +648,6 @@ void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float
float dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
-
r_bake[mp] = mid;
}
@@ -665,9 +658,9 @@ void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float
}
void Curve2D::_bake() const {
-
- if (!baked_cache_dirty)
+ if (!baked_cache_dirty) {
return;
+ }
baked_max_ofs = 0;
baked_cache_dirty = false;
@@ -678,7 +671,6 @@ void Curve2D::_bake() const {
}
if (points.size() == 1) {
-
baked_point_cache.resize(1);
baked_point_cache.set(0, points[0].pos);
return;
@@ -690,15 +682,14 @@ void Curve2D::_bake() const {
pointlist.push_back(pos); //start always from origin
for (int i = 0; i < points.size() - 1; i++) {
-
float step = 0.1; // at least 10 substeps ought to be enough?
float p = 0;
while (p < 1.0) {
-
float np = p + step;
- if (np > 1.0)
+ if (np > 1.0) {
np = 1.0;
+ }
Vector2 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
float d = pos.distance_to(npp);
@@ -713,14 +704,14 @@ void Curve2D::_bake() const {
float mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
-
npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
d = pos.distance_to(npp);
- if (bake_interval < d)
+ if (bake_interval < d) {
hi = mid;
- else
+ } else {
low = mid;
+ }
mid = low + (hi - low) * 0.5;
}
@@ -728,7 +719,6 @@ void Curve2D::_bake() const {
p = mid;
pointlist.push_back(pos);
} else {
-
p = np;
}
}
@@ -741,42 +731,45 @@ void Curve2D::_bake() const {
pointlist.push_back(lastpos);
baked_point_cache.resize(pointlist.size());
- PoolVector2Array::Write w = baked_point_cache.write();
+ Vector2 *w = baked_point_cache.ptrw();
int idx = 0;
for (List<Vector2>::Element *E = pointlist.front(); E; E = E->next()) {
-
w[idx] = E->get();
idx++;
}
}
float Curve2D::get_baked_length() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_max_ofs;
}
-Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
- if (baked_cache_dirty)
+Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
int bpc = baked_point_cache.size();
- PoolVector2Array::Read r = baked_point_cache.read();
+ const Vector2 *r = baked_point_cache.ptr();
- if (p_offset < 0)
+ if (p_offset < 0) {
return r[0];
- if (p_offset >= baked_max_ofs)
+ }
+ if (p_offset >= baked_max_ofs) {
return r[bpc - 1];
+ }
int idx = Math::floor((double)p_offset / (double)bake_interval);
float frac = Math::fmod(p_offset, (float)bake_interval);
@@ -784,56 +777,56 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
if (idx >= bpc - 1) {
return r[bpc - 1];
} else if (idx == bpc - 2) {
- if (frac > 0)
+ if (frac > 0) {
frac /= Math::fmod(baked_max_ofs, bake_interval);
+ }
} else {
frac /= bake_interval;
}
if (p_cubic) {
-
Vector2 pre = idx > 0 ? r[idx - 1] : r[idx];
Vector2 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1];
return r[idx].cubic_interpolate(r[idx + 1], pre, post, frac);
} else {
- return r[idx].linear_interpolate(r[idx + 1], frac);
+ return r[idx].lerp(r[idx + 1], frac);
}
}
-PoolVector2Array Curve2D::get_baked_points() const {
-
- if (baked_cache_dirty)
+PackedVector2Array Curve2D::get_baked_points() const {
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_point_cache;
}
void Curve2D::set_bake_interval(float p_tolerance) {
-
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
float Curve2D::get_bake_interval() const {
-
return bake_interval;
}
Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
- PoolVector2Array::Read r = baked_point_cache.read();
+ const Vector2 *r = baked_point_cache.ptr();
Vector2 nearest;
float nearest_dist = -1.0f;
@@ -859,17 +852,19 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve2D.");
- if (pc == 1)
+ if (pc == 1) {
return 0.0f;
+ }
- PoolVector2Array::Read r = baked_point_cache.read();
+ const Vector2 *r = baked_point_cache.ptr();
float nearest = 0.0f;
float nearest_dist = -1.0f;
@@ -896,38 +891,33 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
}
Dictionary Curve2D::_get_data() const {
-
Dictionary dc;
- PoolVector2Array d;
+ PackedVector2Array d;
d.resize(points.size() * 3);
- PoolVector2Array::Write w = d.write();
+ Vector2 *w = d.ptrw();
for (int i = 0; i < points.size(); i++) {
-
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
w[i * 3 + 2] = points[i].pos;
}
- w = PoolVector2Array::Write();
-
dc["points"] = d;
return dc;
}
-void Curve2D::_set_data(const Dictionary &p_data) {
+void Curve2D::_set_data(const Dictionary &p_data) {
ERR_FAIL_COND(!p_data.has("points"));
- PoolVector2Array rp = p_data["points"];
+ PackedVector2Array rp = p_data["points"];
int pc = rp.size();
ERR_FAIL_COND(pc % 3 != 0);
points.resize(pc / 3);
- PoolVector2Array::Read r = rp.read();
+ const Vector2 *r = rp.ptr();
for (int i = 0; i < points.size(); i++) {
-
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
points.write[i].pos = r[i * 3 + 2];
@@ -936,34 +926,30 @@ void Curve2D::_set_data(const Dictionary &p_data) {
baked_cache_dirty = true;
}
-PoolVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const {
-
- PoolVector2Array tess;
+PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const {
+ PackedVector2Array tess;
if (points.size() == 0) {
return tess;
}
- Vector<Map<float, Vector2> > midpoints;
+ Vector<Map<float, Vector2>> midpoints;
midpoints.resize(points.size() - 1);
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
-
_bake_segment2d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
tess.resize(pc);
- PoolVector2Array::Write bpw = tess.write();
+ Vector2 *bpw = tess.ptrw();
bpw[0] = points[0].pos;
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
-
for (Map<float, Vector2>::Element *E = midpoints[i].front(); E; E = E->next()) {
-
pidx++;
bpw[pidx] = E->get();
}
@@ -972,13 +958,10 @@ PoolVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const
bpw[pidx] = points[i + 1].pos;
}
- bpw = PoolVector2Array::Write();
-
return tess;
}
void Curve2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve2D::get_point_count);
ClassDB::bind_method(D_METHOD("add_point", "position", "in", "out", "at_position"), &Curve2D::add_point, DEFVAL(Vector2()), DEFVAL(Vector2()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_point_position", "idx", "position"), &Curve2D::set_point_position);
@@ -1005,7 +988,7 @@ void Curve2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_data"), &Curve2D::_get_data);
ClassDB::bind_method(D_METHOD("_set_data"), &Curve2D::_set_data);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
@@ -1026,67 +1009,64 @@ Curve2D::Curve2D() {
/***********************************************************************************/
int Curve3D::get_point_count() const {
-
return points.size();
}
-void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
+void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
Point n;
n.pos = p_pos;
n.in = p_in;
n.out = p_out;
- if (p_atpos >= 0 && p_atpos < points.size())
+ if (p_atpos >= 0 && p_atpos < points.size()) {
points.insert(p_atpos, n);
- else
+ } else {
points.push_back(n);
+ }
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) {
+void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) {
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].pos = p_pos;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector3 Curve3D::get_point_position(int p_index) const {
+Vector3 Curve3D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
return points[p_index].pos;
}
void Curve3D::set_point_tilt(int p_index, float p_tilt) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].tilt = p_tilt;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve3D::get_point_tilt(int p_index) const {
+float Curve3D::get_point_tilt(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), 0);
return points[p_index].tilt;
}
void Curve3D::set_point_in(int p_index, const Vector3 &p_in) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].in = p_in;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector3 Curve3D::get_point_in(int p_index) const {
+Vector3 Curve3D::get_point_in(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
return points[p_index].in;
}
void Curve3D::set_point_out(int p_index, const Vector3 &p_out) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].out = p_out;
@@ -1095,13 +1075,11 @@ void Curve3D::set_point_out(int p_index, const Vector3 &p_out) {
}
Vector3 Curve3D::get_point_out(int p_index) const {
-
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
return points[p_index].out;
}
void Curve3D::remove_point(int p_index) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.remove(p_index);
baked_cache_dirty = true;
@@ -1109,7 +1087,6 @@ void Curve3D::remove_point(int p_index) {
}
void Curve3D::clear_points() {
-
if (!points.empty()) {
points.clear();
baked_cache_dirty = true;
@@ -1118,14 +1095,14 @@ void Curve3D::clear_points() {
}
Vector3 Curve3D::interpolate(int p_index, float p_offset) const {
-
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector3());
- if (p_index >= pc - 1)
+ if (p_index >= pc - 1) {
return points[pc - 1].pos;
- else if (p_index < 0)
+ } else if (p_index < 0) {
return points[0].pos;
+ }
Vector3 p0 = points[p_index].pos;
Vector3 p1 = p0 + points[p_index].out;
@@ -1136,17 +1113,16 @@ Vector3 Curve3D::interpolate(int p_index, float p_offset) const {
}
Vector3 Curve3D::interpolatef(real_t p_findex) const {
-
- if (p_findex < 0)
+ if (p_findex < 0) {
p_findex = 0;
- else if (p_findex >= points.size())
+ } else if (p_findex >= points.size()) {
p_findex = points.size();
+ }
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const {
-
float mp = p_begin + (p_end - p_begin) * 0.5;
Vector3 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
@@ -1157,7 +1133,6 @@ void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float
float dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
-
r_bake[mp] = mid;
}
if (p_depth < p_max_depth) {
@@ -1167,9 +1142,9 @@ void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float
}
void Curve3D::_bake() const {
-
- if (!baked_cache_dirty)
+ if (!baked_cache_dirty) {
return;
+ }
baked_max_ofs = 0;
baked_cache_dirty = false;
@@ -1182,18 +1157,17 @@ void Curve3D::_bake() const {
}
if (points.size() == 1) {
-
baked_point_cache.resize(1);
baked_point_cache.set(0, points[0].pos);
baked_tilt_cache.resize(1);
baked_tilt_cache.set(0, points[0].tilt);
if (up_vector_enabled) {
-
baked_up_vector_cache.resize(1);
baked_up_vector_cache.set(0, Vector3(0, 1, 0));
- } else
+ } else {
baked_up_vector_cache.resize(0);
+ }
return;
}
@@ -1203,15 +1177,14 @@ void Curve3D::_bake() const {
pointlist.push_back(Plane(pos, points[0].tilt));
for (int i = 0; i < points.size() - 1; i++) {
-
float step = 0.1; // at least 10 substeps ought to be enough?
float p = 0;
while (p < 1.0) {
-
float np = p + step;
- if (np > 1.0)
+ if (np > 1.0) {
np = 1.0;
+ }
Vector3 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
float d = pos.distance_to(npp);
@@ -1226,14 +1199,14 @@ void Curve3D::_bake() const {
float mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
-
npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
d = pos.distance_to(npp);
- if (bake_interval < d)
+ if (bake_interval < d) {
hi = mid;
- else
+ } else {
low = mid;
+ }
mid = low + (hi - low) * 0.5;
}
@@ -1244,7 +1217,6 @@ void Curve3D::_bake() const {
post.d = Math::lerp(points[i].tilt, points[i + 1].tilt, mid);
pointlist.push_back(post);
} else {
-
p = np;
}
}
@@ -1258,14 +1230,14 @@ void Curve3D::_bake() const {
pointlist.push_back(Plane(lastpos, lastilt));
baked_point_cache.resize(pointlist.size());
- PoolVector3Array::Write w = baked_point_cache.write();
+ Vector3 *w = baked_point_cache.ptrw();
int idx = 0;
baked_tilt_cache.resize(pointlist.size());
- PoolRealArray::Write wt = baked_tilt_cache.write();
+ real_t *wt = baked_tilt_cache.ptrw();
baked_up_vector_cache.resize(up_vector_enabled ? pointlist.size() : 0);
- PoolVector3Array::Write up_write = baked_up_vector_cache.write();
+ Vector3 *up_write = baked_up_vector_cache.ptrw();
Vector3 sideways;
Vector3 up;
@@ -1276,7 +1248,6 @@ void Curve3D::_bake() const {
Vector3 prev_forward = Vector3(0, 0, 1);
for (List<Plane>::Element *E = pointlist.front(); E; E = E->next()) {
-
w[idx] = E->get().normal;
wt[idx] = E->get().d;
@@ -1300,8 +1271,9 @@ void Curve3D::_bake() const {
up = forward.cross(sideways).normalized();
}
- if (idx == 1)
+ if (idx == 1) {
up_write[0] = up;
+ }
up_write[idx] = up;
@@ -1314,31 +1286,35 @@ void Curve3D::_bake() const {
}
float Curve3D::get_baked_length() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_max_ofs;
}
-Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
- if (baked_cache_dirty)
+Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
int bpc = baked_point_cache.size();
- PoolVector3Array::Read r = baked_point_cache.read();
+ const Vector3 *r = baked_point_cache.ptr();
- if (p_offset < 0)
+ if (p_offset < 0) {
return r[0];
- if (p_offset >= baked_max_ofs)
+ }
+ if (p_offset >= baked_max_ofs) {
return r[bpc - 1];
+ }
int idx = Math::floor((double)p_offset / (double)bake_interval);
float frac = Math::fmod(p_offset, bake_interval);
@@ -1346,41 +1322,44 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
if (idx >= bpc - 1) {
return r[bpc - 1];
} else if (idx == bpc - 2) {
- if (frac > 0)
+ if (frac > 0) {
frac /= Math::fmod(baked_max_ofs, bake_interval);
+ }
} else {
frac /= bake_interval;
}
if (p_cubic) {
-
Vector3 pre = idx > 0 ? r[idx - 1] : r[idx];
Vector3 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1];
return r[idx].cubic_interpolate(r[idx + 1], pre, post, frac);
} else {
- return r[idx].linear_interpolate(r[idx + 1], frac);
+ return r[idx].lerp(r[idx + 1], frac);
}
}
float Curve3D::interpolate_baked_tilt(float p_offset) const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_tilt_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, 0, "No tilts in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_tilt_cache.get(0);
+ }
int bpc = baked_tilt_cache.size();
- PoolRealArray::Read r = baked_tilt_cache.read();
+ const real_t *r = baked_tilt_cache.ptr();
- if (p_offset < 0)
+ if (p_offset < 0) {
return r[0];
- if (p_offset >= baked_max_ofs)
+ }
+ if (p_offset >= baked_max_ofs) {
return r[bpc - 1];
+ }
int idx = Math::floor((double)p_offset / (double)bake_interval);
float frac = Math::fmod(p_offset, bake_interval);
@@ -1388,8 +1367,9 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
if (idx >= bpc - 1) {
return r[bpc - 1];
} else if (idx == bpc - 2) {
- if (frac > 0)
+ if (frac > 0) {
frac /= Math::fmod(baked_max_ofs, bake_interval);
+ }
} else {
frac /= bake_interval;
}
@@ -1398,29 +1378,31 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
}
Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
// curve may not have baked up vectors
int count = baked_up_vector_cache.size();
ERR_FAIL_COND_V_MSG(count == 0, Vector3(0, 1, 0), "No up vectors in Curve3D.");
- if (count == 1)
+ if (count == 1) {
return baked_up_vector_cache.get(0);
+ }
- PoolVector3Array::Read r = baked_up_vector_cache.read();
- PoolVector3Array::Read rp = baked_point_cache.read();
- PoolRealArray::Read rt = baked_tilt_cache.read();
+ const Vector3 *r = baked_up_vector_cache.ptr();
+ const Vector3 *rp = baked_point_cache.ptr();
+ const real_t *rt = baked_tilt_cache.ptr();
float offset = CLAMP(p_offset, 0.0f, baked_max_ofs);
int idx = Math::floor((double)offset / (double)bake_interval);
float frac = Math::fmod(offset, bake_interval) / bake_interval;
- if (idx == count - 1)
+ if (idx == count - 1) {
return p_apply_tilt ? r[idx].rotated((rp[idx] - rp[idx - 1]).normalized(), rt[idx]) : r[idx];
+ }
Vector3 forward = (rp[idx + 1] - rp[idx]).normalized();
Vector3 up = r[idx];
@@ -1433,34 +1415,35 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt)
Vector3 axis = up.cross(up1);
- if (axis.length_squared() < CMP_EPSILON2)
+ if (axis.length_squared() < CMP_EPSILON2) {
axis = forward;
- else
+ } else {
axis.normalize();
+ }
return up.rotated(axis, up.angle_to(up1) * frac);
}
-PoolVector3Array Curve3D::get_baked_points() const {
-
- if (baked_cache_dirty)
+PackedVector3Array Curve3D::get_baked_points() const {
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_point_cache;
}
-PoolRealArray Curve3D::get_baked_tilts() const {
-
- if (baked_cache_dirty)
+PackedFloat32Array Curve3D::get_baked_tilts() const {
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_tilt_cache;
}
-PoolVector3Array Curve3D::get_baked_up_vectors() const {
-
- if (baked_cache_dirty)
+PackedVector3Array Curve3D::get_baked_up_vectors() const {
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_up_vector_cache;
}
@@ -1468,17 +1451,19 @@ PoolVector3Array Curve3D::get_baked_up_vectors() const {
Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
- PoolVector3Array::Read r = baked_point_cache.read();
+ const Vector3 *r = baked_point_cache.ptr();
Vector3 nearest;
float nearest_dist = -1.0f;
@@ -1504,17 +1489,19 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return 0.0f;
+ }
- PoolVector3Array::Read r = baked_point_cache.read();
+ const Vector3 *r = baked_point_cache.ptr();
float nearest = 0.0f;
float nearest_dist = -1.0f;
@@ -1541,71 +1528,61 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
}
void Curve3D::set_bake_interval(float p_tolerance) {
-
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
float Curve3D::get_bake_interval() const {
-
return bake_interval;
}
void Curve3D::set_up_vector_enabled(bool p_enable) {
-
up_vector_enabled = p_enable;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
bool Curve3D::is_up_vector_enabled() const {
-
return up_vector_enabled;
}
Dictionary Curve3D::_get_data() const {
-
Dictionary dc;
- PoolVector3Array d;
+ PackedVector3Array d;
d.resize(points.size() * 3);
- PoolVector3Array::Write w = d.write();
- PoolRealArray t;
+ Vector3 *w = d.ptrw();
+ PackedFloat32Array t;
t.resize(points.size());
- PoolRealArray::Write wt = t.write();
+ real_t *wt = t.ptrw();
for (int i = 0; i < points.size(); i++) {
-
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
w[i * 3 + 2] = points[i].pos;
wt[i] = points[i].tilt;
}
- w = PoolVector3Array::Write();
- wt = PoolRealArray::Write();
-
dc["points"] = d;
dc["tilts"] = t;
return dc;
}
-void Curve3D::_set_data(const Dictionary &p_data) {
+void Curve3D::_set_data(const Dictionary &p_data) {
ERR_FAIL_COND(!p_data.has("points"));
ERR_FAIL_COND(!p_data.has("tilts"));
- PoolVector3Array rp = p_data["points"];
+ PackedVector3Array rp = p_data["points"];
int pc = rp.size();
ERR_FAIL_COND(pc % 3 != 0);
points.resize(pc / 3);
- PoolVector3Array::Read r = rp.read();
- PoolRealArray rtl = p_data["tilts"];
- PoolRealArray::Read rt = rtl.read();
+ const Vector3 *r = rp.ptr();
+ PackedFloat32Array rtl = p_data["tilts"];
+ const real_t *rt = rtl.ptr();
for (int i = 0; i < points.size(); i++) {
-
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
points.write[i].pos = r[i * 3 + 2];
@@ -1615,34 +1592,30 @@ void Curve3D::_set_data(const Dictionary &p_data) {
baked_cache_dirty = true;
}
-PoolVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const {
-
- PoolVector3Array tess;
+PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const {
+ PackedVector3Array tess;
if (points.size() == 0) {
return tess;
}
- Vector<Map<float, Vector3> > midpoints;
+ Vector<Map<float, Vector3>> midpoints;
midpoints.resize(points.size() - 1);
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
-
_bake_segment3d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
tess.resize(pc);
- PoolVector3Array::Write bpw = tess.write();
+ Vector3 *bpw = tess.ptrw();
bpw[0] = points[0].pos;
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
-
for (Map<float, Vector3>::Element *E = midpoints[i].front(); E; E = E->next()) {
-
pidx++;
bpw[pidx] = E->get();
}
@@ -1651,13 +1624,10 @@ PoolVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const
bpw[pidx] = points[i + 1].pos;
}
- bpw = PoolVector3Array::Write();
-
return tess;
}
void Curve3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve3D::get_point_count);
ClassDB::bind_method(D_METHOD("add_point", "position", "in", "out", "at_position"), &Curve3D::add_point, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_point_position", "idx", "position"), &Curve3D::set_point_position);
@@ -1691,7 +1661,7 @@ void Curve3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_data"), &Curve3D::_get_data);
ClassDB::bind_method(D_METHOD("_set_data"), &Curve3D::_set_data);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
ADD_GROUP("Up Vector", "up_vector_");
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index b02466534c..57ddaf897d 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -68,7 +68,6 @@ public:
real_t p_right = 0,
TangentMode p_left_mode = TANGENT_FREE,
TangentMode p_right_mode = TANGENT_FREE) {
-
pos = p_pos;
left_tangent = p_left;
right_tangent = p_right;
@@ -149,11 +148,9 @@ private:
VARIANT_ENUM_CAST(Curve::TangentMode)
class Curve2D : public Resource {
-
GDCLASS(Curve2D, Resource);
struct Point {
-
Vector2 in;
Vector2 out;
Vector2 pos;
@@ -162,13 +159,12 @@ class Curve2D : public Resource {
Vector<Point> points;
struct BakedPoint {
-
float ofs;
Vector2 point;
};
mutable bool baked_cache_dirty;
- mutable PoolVector2Array baked_point_cache;
+ mutable PackedVector2Array baked_point_cache;
mutable float baked_max_ofs;
void _bake() const;
@@ -202,21 +198,19 @@ public:
float get_baked_length() const;
Vector2 interpolate_baked(float p_offset, bool p_cubic = false) const;
- PoolVector2Array get_baked_points() const; //useful for going through
+ PackedVector2Array get_baked_points() const; //useful for going through
Vector2 get_closest_point(const Vector2 &p_to_point) const;
float get_closest_offset(const Vector2 &p_to_point) const;
- PoolVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
+ PackedVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
Curve2D();
};
class Curve3D : public Resource {
-
GDCLASS(Curve3D, Resource);
struct Point {
-
Vector3 in;
Vector3 out;
Vector3 pos;
@@ -228,15 +222,14 @@ class Curve3D : public Resource {
Vector<Point> points;
struct BakedPoint {
-
float ofs;
Vector3 point;
};
mutable bool baked_cache_dirty;
- mutable PoolVector3Array baked_point_cache;
- mutable PoolRealArray baked_tilt_cache;
- mutable PoolVector3Array baked_up_vector_cache;
+ mutable PackedVector3Array baked_point_cache;
+ mutable PackedFloat32Array baked_tilt_cache;
+ mutable PackedVector3Array baked_up_vector_cache;
mutable float baked_max_ofs;
void _bake() const;
@@ -277,13 +270,13 @@ public:
Vector3 interpolate_baked(float p_offset, bool p_cubic = false) const;
float interpolate_baked_tilt(float p_offset) const;
Vector3 interpolate_baked_up_vector(float p_offset, bool p_apply_tilt = false) const;
- PoolVector3Array get_baked_points() const; //useful for going through
- PoolRealArray get_baked_tilts() const; //useful for going through
- PoolVector3Array get_baked_up_vectors() const;
+ PackedVector3Array get_baked_points() const; //useful for going through
+ PackedFloat32Array get_baked_tilts() const; //useful for going through
+ PackedVector3Array get_baked_up_vectors() const;
Vector3 get_closest_point(const Vector3 &p_to_point) const;
float get_closest_offset(const Vector3 &p_to_point) const;
- PoolVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
+ PackedVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
Curve3D();
};
diff --git a/scene/resources/cylinder_shape.cpp b/scene/resources/cylinder_shape_3d.cpp
index d9f6e4f054..ad64541247 100644
--- a/scene/resources/cylinder_shape.cpp
+++ b/scene/resources/cylinder_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* cylinder_shape.cpp */
+/* cylinder_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "cylinder_shape.h"
-#include "servers/physics_server.h"
-
-Vector<Vector3> CylinderShape::get_debug_mesh_lines() {
+#include "cylinder_shape_3d.h"
+#include "servers/physics_server_3d.h"
+Vector<Vector3> CylinderShape3D::get_debug_mesh_lines() const {
float radius = get_radius();
float height = get_height();
@@ -40,7 +39,6 @@ Vector<Vector3> CylinderShape::get_debug_mesh_lines() {
Vector3 d(0, height * 0.5, 0);
for (int i = 0; i < 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
@@ -53,7 +51,6 @@ Vector<Vector3> CylinderShape::get_debug_mesh_lines() {
points.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 90 == 0) {
-
points.push_back(Vector3(a.x, 0, a.y) + d);
points.push_back(Vector3(a.x, 0, a.y) - d);
}
@@ -62,55 +59,52 @@ Vector<Vector3> CylinderShape::get_debug_mesh_lines() {
return points;
}
-void CylinderShape::_update_shape() {
+real_t CylinderShape3D::get_enclosing_radius() const {
+ return Vector2(radius, height * 0.5).length();
+}
+void CylinderShape3D::_update_shape() {
Dictionary d;
d["radius"] = radius;
d["height"] = height;
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), d);
- Shape::_update_shape();
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);
+ Shape3D::_update_shape();
}
-void CylinderShape::set_radius(float p_radius) {
-
+void CylinderShape3D::set_radius(float p_radius) {
radius = p_radius;
_update_shape();
notify_change_to_owners();
_change_notify("radius");
}
-float CylinderShape::get_radius() const {
-
+float CylinderShape3D::get_radius() const {
return radius;
}
-void CylinderShape::set_height(float p_height) {
-
+void CylinderShape3D::set_height(float p_height) {
height = p_height;
_update_shape();
notify_change_to_owners();
_change_notify("height");
}
-float CylinderShape::get_height() const {
-
+float CylinderShape3D::get_height() const {
return height;
}
-void CylinderShape::_bind_methods() {
+void CylinderShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CylinderShape3D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &CylinderShape3D::get_radius);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &CylinderShape3D::set_height);
+ ClassDB::bind_method(D_METHOD("get_height"), &CylinderShape3D::get_height);
- ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CylinderShape::set_radius);
- ClassDB::bind_method(D_METHOD("get_radius"), &CylinderShape::get_radius);
- ClassDB::bind_method(D_METHOD("set_height", "height"), &CylinderShape::set_height);
- ClassDB::bind_method(D_METHOD("get_height"), &CylinderShape::get_height);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height");
}
-CylinderShape::CylinderShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CYLINDER)) {
-
+CylinderShape3D::CylinderShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CYLINDER)) {
radius = 1.0;
height = 2.0;
_update_shape();
diff --git a/scene/resources/cylinder_shape.h b/scene/resources/cylinder_shape_3d.h
index ebddd4d92f..e579e1f7cf 100644
--- a/scene/resources/cylinder_shape.h
+++ b/scene/resources/cylinder_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* cylinder_shape.h */
+/* cylinder_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,20 +28,19 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CYLINDER_SHAPE_H
-#define CYLINDER_SHAPE_H
+#ifndef CYLINDER_SHAPE_3D_H
+#define CYLINDER_SHAPE_3D_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class CylinderShape : public Shape {
-
- GDCLASS(CylinderShape, Shape);
+class CylinderShape3D : public Shape3D {
+ GDCLASS(CylinderShape3D, Shape3D);
float radius;
float height;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
void set_radius(float p_radius);
@@ -49,9 +48,10 @@ public:
void set_height(float p_height);
float get_height() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- CylinderShape();
+ CylinderShape3D();
};
#endif // CYLINDER_SHAPE_H
diff --git a/scene/resources/default_theme/SCsub b/scene/resources/default_theme/SCsub
index b01e2fd54d..fc61250247 100644
--- a/scene/resources/default_theme/SCsub
+++ b/scene/resources/default_theme/SCsub
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-Import('env')
+Import("env")
env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/scene/resources/default_theme/bookmark.png b/scene/resources/default_theme/bookmark.png
new file mode 100644
index 0000000000..9718cf53b6
--- /dev/null
+++ b/scene/resources/default_theme/bookmark.png
Binary files differ
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index cc76df62e5..f65f78b332 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -38,38 +38,25 @@
#include "font_hidpi.inc"
#include "font_lodpi.inc"
-typedef Map<const void *, Ref<ImageTexture> > TexCacheMap;
+typedef Map<const void *, Ref<ImageTexture>> TexCacheMap;
static TexCacheMap *tex_cache;
static float scale = 1;
template <class T>
static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) {
-
Ref<ImageTexture> texture;
if (tex_cache->has(p_src)) {
texture = (*tex_cache)[p_src];
} else {
-
texture = Ref<ImageTexture>(memnew(ImageTexture));
Ref<Image> img = memnew(Image(p_src));
+ const Size2 orig_size = Size2(img->get_width(), img->get_height());
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
- if (scale > 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
-
- img->convert(Image::FORMAT_RGBA8);
- img->expand_x2_hq2x();
- if (scale != 2.0) {
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
- } else if (scale < 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
- img->convert(Image::FORMAT_RGBA8);
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
-
- texture->create_from_image(img, ImageTexture::FLAG_FILTER);
+ texture->create_from_image(img);
(*tex_cache)[p_src] = texture;
}
@@ -89,7 +76,6 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl
}
static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, float p_top, float p_right, float p_botton) {
-
p_sbox->set_expand_margin_size(MARGIN_LEFT, p_left * scale);
p_sbox->set_expand_margin_size(MARGIN_TOP, p_top * scale);
p_sbox->set_expand_margin_size(MARGIN_RIGHT, p_right * scale);
@@ -98,30 +84,18 @@ static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left,
}
template <class T>
-static Ref<Texture> make_icon(T p_src) {
-
+static Ref<Texture2D> make_icon(T p_src) {
Ref<ImageTexture> texture(memnew(ImageTexture));
Ref<Image> img = memnew(Image(p_src));
- if (scale > 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
-
- img->convert(Image::FORMAT_RGBA8);
- img->expand_x2_hq2x();
- if (scale != 2.0) {
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
- } else if (scale < 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
- img->convert(Image::FORMAT_RGBA8);
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
- texture->create_from_image(img, ImageTexture::FLAG_FILTER);
+ const Size2 orig_size = Size2(img->get_width(), img->get_height());
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
+ texture->create_from_image(img);
return texture;
}
static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) {
-
Ref<BitmapFont> font(memnew(BitmapFont));
Ref<Image> image = memnew(Image(p_img));
@@ -131,7 +105,6 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, co
font->add_texture(tex);
for (int i = 0; i < p_charcount; i++) {
-
const int *c = &p_char_rects[i * 8];
int chr = c[0];
@@ -147,7 +120,6 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, co
}
for (int i = 0; i < p_kerning_count; i++) {
-
font->add_kerning_pair(p_kernings[i * 3 + 0], p_kernings[i * 3 + 1], p_kernings[i * 3 + 2]);
}
@@ -158,7 +130,6 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, co
}
static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1) {
-
Ref<StyleBox> style(memnew(StyleBoxEmpty));
style->set_default_margin(MARGIN_LEFT, p_margin_left * scale);
@@ -169,8 +140,7 @@ static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margi
return style;
}
-void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale) {
-
+void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale) {
scale = p_scale;
tex_cache = memnew(TexCacheMap);
@@ -188,6 +158,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// Panel
theme->set_stylebox("panel", "Panel", make_stylebox(panel_bg_png, 0, 0, 0, 0));
+ theme->set_stylebox("panel_fg", "Panel", make_stylebox(panel_bg_png, 0, 0, 0, 0));
// Focus
@@ -210,7 +181,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("disabled", "Button", sb_button_disabled);
theme->set_stylebox("focus", "Button", sb_button_focus);
- theme->set_font("font", "Button", default_font);
+ theme->set_font("font", "Button", Ref<Font>());
theme->set_color("font_color", "Button", control_font_color);
theme->set_color("font_color_pressed", "Button", control_font_color_pressed);
@@ -223,7 +194,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("focus", "LinkButton", focus);
- theme->set_font("font", "LinkButton", default_font);
+ theme->set_font("font", "LinkButton", Ref<Font>());
theme->set_color("font_color", "LinkButton", control_font_color);
theme->set_color("font_color_pressed", "LinkButton", control_font_color_pressed);
@@ -239,7 +210,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("disabled", "ColorPickerButton", sb_button_disabled);
theme->set_stylebox("focus", "ColorPickerButton", sb_button_focus);
- theme->set_font("font", "ColorPickerButton", default_font);
+ theme->set_font("font", "ColorPickerButton", Ref<Font>());
theme->set_color("font_color", "ColorPickerButton", Color(1, 1, 1, 1));
theme->set_color("font_color_pressed", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1));
@@ -248,22 +219,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("hseparation", "ColorPickerButton", 2 * scale);
- // ToolButton
-
- theme->set_stylebox("normal", "ToolButton", make_empty_stylebox(6, 4, 6, 4));
- theme->set_stylebox("pressed", "ToolButton", make_stylebox(button_pressed_png, 4, 4, 4, 4, 6, 4, 6, 4));
- theme->set_stylebox("hover", "ToolButton", make_stylebox(button_normal_png, 4, 4, 4, 4, 6, 4, 6, 4));
- theme->set_stylebox("disabled", "ToolButton", make_empty_stylebox(6, 4, 6, 4));
- theme->set_stylebox("focus", "ToolButton", focus);
- theme->set_font("font", "ToolButton", default_font);
-
- theme->set_color("font_color", "ToolButton", control_font_color);
- theme->set_color("font_color_pressed", "ToolButton", control_font_color_pressed);
- theme->set_color("font_color_hover", "ToolButton", control_font_color_hover);
- theme->set_color("font_color_disabled", "ToolButton", Color(0.9, 0.95, 1, 0.3));
-
- theme->set_constant("hseparation", "ToolButton", 3);
-
// OptionButton
Ref<StyleBox> sb_optbutton_normal = sb_expand(make_stylebox(option_button_normal_png, 4, 4, 21, 4, 6, 3, 9, 3), 2, 2, 2, 2);
@@ -280,7 +235,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("arrow", "OptionButton", make_icon(option_arrow_png));
- theme->set_font("font", "OptionButton", default_font);
+ theme->set_font("font", "OptionButton", Ref<Font>());
theme->set_color("font_color", "OptionButton", control_font_color);
theme->set_color("font_color_pressed", "OptionButton", control_font_color_pressed);
@@ -298,7 +253,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("disabled", "MenuButton", sb_button_disabled);
theme->set_stylebox("focus", "MenuButton", sb_button_focus);
- theme->set_font("font", "MenuButton", default_font);
+ theme->set_font("font", "MenuButton", Ref<Font>());
theme->set_color("font_color", "MenuButton", control_font_color);
theme->set_color("font_color_pressed", "MenuButton", control_font_color_pressed);
@@ -332,7 +287,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("radio_checked", "CheckBox", make_icon(radio_checked_png));
theme->set_icon("radio_unchecked", "CheckBox", make_icon(radio_unchecked_png));
- theme->set_font("font", "CheckBox", default_font);
+ theme->set_font("font", "CheckBox", Ref<Font>());
theme->set_color("font_color", "CheckBox", control_font_color);
theme->set_color("font_color_pressed", "CheckBox", control_font_color_pressed);
@@ -363,7 +318,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("off", "CheckButton", make_icon(toggle_off_png));
theme->set_icon("off_disabled", "CheckButton", make_icon(toggle_off_disabled_png));
- theme->set_font("font", "CheckButton", default_font);
+ theme->set_font("font", "CheckButton", Ref<Font>());
theme->set_color("font_color", "CheckButton", control_font_color);
theme->set_color("font_color_pressed", "CheckButton", control_font_color_pressed);
@@ -377,7 +332,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// Label
theme->set_stylebox("normal", "Label", memnew(StyleBoxEmpty));
- theme->set_font("font", "Label", default_font);
+ theme->set_font("font", "Label", Ref<Font>());
theme->set_color("font_color", "Label", Color(1, 1, 1));
theme->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0));
@@ -394,7 +349,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("focus", "LineEdit", focus);
theme->set_stylebox("read_only", "LineEdit", make_stylebox(line_edit_disabled_png, 6, 6, 6, 6));
- theme->set_font("font", "LineEdit", default_font);
+ theme->set_font("font", "LineEdit", Ref<Font>());
theme->set_color("font_color", "LineEdit", control_font_color);
theme->set_color("font_color_selected", "LineEdit", Color(0, 0, 0));
@@ -413,7 +368,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("bg", "ProgressBar", make_stylebox(progress_bar_png, 4, 4, 4, 4, 0, 0, 0, 0));
theme->set_stylebox("fg", "ProgressBar", make_stylebox(progress_fill_png, 6, 6, 6, 6, 2, 1, 2, 1));
- theme->set_font("font", "ProgressBar", default_font);
+ theme->set_font("font", "ProgressBar", Ref<Font>());
theme->set_color("font_color", "ProgressBar", control_font_color_hover);
theme->set_color("font_color_shadow", "ProgressBar", Color(0, 0, 0));
@@ -427,10 +382,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("tab", "TextEdit", make_icon(tab_png));
theme->set_icon("space", "TextEdit", make_icon(space_png));
- theme->set_icon("folded", "TextEdit", make_icon(arrow_right_png));
- theme->set_icon("fold", "TextEdit", make_icon(arrow_down_png));
- theme->set_font("font", "TextEdit", default_font);
+ theme->set_font("font", "TextEdit", Ref<Font>());
theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0));
theme->set_color("completion_background_color", "TextEdit", Color(0.17, 0.16, 0.2));
@@ -443,20 +396,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_color_readonly", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
theme->set_color("selection_color", "TextEdit", font_color_selection);
theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4));
- theme->set_color("bookmark_color", "TextEdit", Color(0.08, 0.49, 0.98));
- theme->set_color("breakpoint_color", "TextEdit", Color(0.8, 0.8, 0.4, 0.2));
- theme->set_color("executing_line_color", "TextEdit", Color(0.2, 0.8, 0.2, 0.4));
theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8));
theme->set_color("caret_color", "TextEdit", control_font_color);
theme->set_color("caret_background_color", "TextEdit", Color(0, 0, 0));
- theme->set_color("symbol_color", "TextEdit", control_font_color_hover);
theme->set_color("brace_mismatch_color", "TextEdit", Color(1, 0.2, 0.2));
- theme->set_color("line_number_color", "TextEdit", Color(0.67, 0.67, 0.67, 0.4));
- theme->set_color("safe_line_number_color", "TextEdit", Color(0.67, 0.78, 0.67, 0.6));
- theme->set_color("function_color", "TextEdit", Color(0.4, 0.64, 0.81));
- theme->set_color("member_variable_color", "TextEdit", Color(0.9, 0.31, 0.35));
- theme->set_color("number_color", "TextEdit", Color(0.92, 0.58, 0.2));
theme->set_color("word_highlighted_color", "TextEdit", Color(0.8, 0.9, 0.9, 0.15));
theme->set_constant("completion_lines", "TextEdit", 7);
@@ -464,7 +408,51 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("completion_scroll_width", "TextEdit", 3);
theme->set_constant("line_spacing", "TextEdit", 4 * scale);
- Ref<Texture> empty_icon = memnew(ImageTexture);
+ // CodeEdit
+ theme->set_stylebox("normal", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0));
+ theme->set_stylebox("focus", "CodeEdit", focus);
+ theme->set_stylebox("read_only", "CodeEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4, 0, 0, 0, 0));
+ theme->set_stylebox("completion", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0));
+
+ theme->set_icon("tab", "CodeEdit", make_icon(tab_png));
+ theme->set_icon("space", "CodeEdit", make_icon(space_png));
+ theme->set_icon("breakpoint", "CodeEdit", make_icon(graph_port_png));
+ theme->set_icon("bookmark", "CodeEdit", make_icon(bookmark_png));
+ theme->set_icon("executing_line", "CodeEdit", make_icon(arrow_right_png));
+ theme->set_icon("can_fold", "CodeEdit", make_icon(arrow_down_png));
+ theme->set_icon("folded", "CodeEdit", make_icon(arrow_right_png));
+
+ theme->set_font("font", "CodeEdit", Ref<Font>());
+
+ theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0));
+ theme->set_color("completion_background_color", "CodeEdit", Color(0.17, 0.16, 0.2));
+ theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27));
+ theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13));
+ theme->set_color("completion_scroll_color", "CodeEdit", control_font_color_pressed);
+ theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67));
+ theme->set_color("font_color", "CodeEdit", control_font_color);
+ theme->set_color("font_color_selected", "CodeEdit", Color(0, 0, 0));
+ theme->set_color("font_color_readonly", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
+ theme->set_color("selection_color", "CodeEdit", font_color_selection);
+ theme->set_color("mark_color", "CodeEdit", Color(1.0, 0.4, 0.4, 0.4));
+ theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8));
+ theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3));
+ theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27));
+ theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8));
+ theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8));
+ theme->set_color("caret_color", "CodeEdit", control_font_color);
+ theme->set_color("caret_background_color", "CodeEdit", Color(0, 0, 0));
+ theme->set_color("brace_mismatch_color", "CodeEdit", Color(1, 0.2, 0.2));
+ theme->set_color("line_number_color", "CodeEdit", Color(0.67, 0.67, 0.67, 0.4));
+ theme->set_color("safe_line_number_color", "CodeEdit", Color(0.67, 0.78, 0.67, 0.6));
+ theme->set_color("word_highlighted_color", "CodeEdit", Color(0.8, 0.9, 0.9, 0.15));
+
+ theme->set_constant("completion_lines", "CodeEdit", 7);
+ theme->set_constant("completion_max_width", "CodeEdit", 50);
+ theme->set_constant("completion_scroll_width", "CodeEdit", 3);
+ theme->set_constant("line_spacing", "CodeEdit", 4 * scale);
+
+ Ref<Texture2D> empty_icon = memnew(ImageTexture);
// HScrollBar
@@ -496,6 +484,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("slider", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
theme->set_stylebox("grabber_area", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
+ theme->set_stylebox("grabber_area_highlight", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
theme->set_icon("grabber", "HSlider", make_icon(hslider_grabber_png));
theme->set_icon("grabber_highlight", "HSlider", make_icon(hslider_grabber_hl_png));
@@ -506,6 +495,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
theme->set_stylebox("grabber_area", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
+ theme->set_stylebox("grabber_area_highlight", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
theme->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png));
theme->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png));
@@ -523,17 +513,19 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// WindowDialog
- theme->set_stylebox("panel", "WindowDialog", sb_expand(make_stylebox(popup_window_png, 10, 26, 10, 8), 8, 24, 8, 6));
- theme->set_constant("scaleborder_size", "WindowDialog", 4 * scale);
+ theme->set_stylebox("panel", "Window", default_style);
+ theme->set_stylebox("window_panel", "Window", sb_expand(make_stylebox(popup_window_png, 10, 26, 10, 8), 8, 24, 8, 6));
+ theme->set_constant("scaleborder_size", "Window", 4 * scale);
- theme->set_font("title_font", "WindowDialog", large_font);
- theme->set_color("title_color", "WindowDialog", Color(0, 0, 0));
- theme->set_constant("title_height", "WindowDialog", 20 * scale);
+ theme->set_font("title_font", "Window", large_font);
+ theme->set_color("title_color", "Window", Color(0, 0, 0));
+ theme->set_constant("title_height", "Window", 20 * scale);
+ theme->set_constant("resize_margin", "Window", 4 * scale);
- theme->set_icon("close", "WindowDialog", make_icon(close_png));
- theme->set_icon("close_highlight", "WindowDialog", make_icon(close_hl_png));
- theme->set_constant("close_h_ofs", "WindowDialog", 18 * scale);
- theme->set_constant("close_v_ofs", "WindowDialog", 18 * scale);
+ theme->set_icon("close", "Window", make_icon(close_png));
+ theme->set_icon("close_highlight", "Window", make_icon(close_hl_png));
+ theme->set_constant("close_h_ofs", "Window", 18 * scale);
+ theme->set_constant("close_v_ofs", "Window", 18 * scale);
// File Dialog
@@ -572,7 +564,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("radio_unchecked", "PopupMenu", make_icon(radio_unchecked_png));
theme->set_icon("submenu", "PopupMenu", make_icon(submenu_png));
- theme->set_font("font", "PopupMenu", default_font);
+ theme->set_font("font", "PopupMenu", Ref<Font>());
theme->set_color("font_color", "PopupMenu", control_font_color);
theme->set_color("font_color_accel", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8));
@@ -607,7 +599,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("port", "GraphNode", make_icon(graph_port_png));
theme->set_icon("close", "GraphNode", make_icon(graph_node_close_png));
theme->set_icon("resizer", "GraphNode", make_icon(window_resizer_png));
- theme->set_font("title_font", "GraphNode", default_font);
+ theme->set_font("title_font", "GraphNode", Ref<Font>());
theme->set_color("title_color", "GraphNode", Color(0, 0, 0, 1));
theme->set_color("close_color", "GraphNode", Color(0, 0, 0, 1));
theme->set_color("resizer_color", "GraphNode", Color(0, 0, 0, 1));
@@ -641,14 +633,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("arrow", "Tree", make_icon(arrow_down_png));
theme->set_icon("arrow_collapsed", "Tree", make_icon(arrow_right_png));
- theme->set_font("title_button_font", "Tree", default_font);
- theme->set_font("font", "Tree", default_font);
+ theme->set_font("title_button_font", "Tree", Ref<Font>());
+ theme->set_font("font", "Tree", Ref<Font>());
theme->set_color("title_button_color", "Tree", control_font_color);
theme->set_color("font_color", "Tree", control_font_color_low);
theme->set_color("font_color_selected", "Tree", control_font_color_pressed);
- theme->set_color("selection_color", "Tree", Color(0.1, 0.1, 1, 0.8));
- theme->set_color("cursor_color", "Tree", Color(0, 0, 0));
theme->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1));
theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2));
theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27));
@@ -673,7 +663,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("vseparation", "ItemList", 2);
theme->set_constant("icon_margin", "ItemList", 4);
theme->set_constant("line_separation", "ItemList", 2 * scale);
- theme->set_font("font", "ItemList", default_font);
+ theme->set_font("font", "ItemList", Ref<Font>());
theme->set_color("font_color", "ItemList", control_font_color_lower);
theme->set_color("font_color_selected", "ItemList", control_font_color_pressed);
theme->set_color("guide_color", "ItemList", Color(0, 0, 0, 0.1));
@@ -701,17 +691,14 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("menu", "TabContainer", make_icon(tab_menu_png));
theme->set_icon("menu_highlight", "TabContainer", make_icon(tab_menu_hl_png));
- theme->set_font("font", "TabContainer", default_font);
+ theme->set_font("font", "TabContainer", Ref<Font>());
theme->set_color("font_color_fg", "TabContainer", control_font_color_hover);
theme->set_color("font_color_bg", "TabContainer", control_font_color_low);
theme->set_color("font_color_disabled", "TabContainer", control_font_color_disabled);
theme->set_constant("side_margin", "TabContainer", 8 * scale);
- theme->set_constant("top_margin", "TabContainer", 24 * scale);
- theme->set_constant("label_valign_fg", "TabContainer", 0 * scale);
- theme->set_constant("label_valign_bg", "TabContainer", 2 * scale);
- theme->set_constant("hseparation", "TabContainer", 4 * scale);
+ theme->set_constant("icon_separation", "TabContainer", 4 * scale);
// Tabs
@@ -728,15 +715,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("decrement_highlight", "Tabs", make_icon(scroll_button_left_hl_png));
theme->set_icon("close", "Tabs", make_icon(tab_close_png));
- theme->set_font("font", "Tabs", default_font);
+ theme->set_font("font", "Tabs", Ref<Font>());
theme->set_color("font_color_fg", "Tabs", control_font_color_hover);
theme->set_color("font_color_bg", "Tabs", control_font_color_low);
theme->set_color("font_color_disabled", "Tabs", control_font_color_disabled);
- theme->set_constant("top_margin", "Tabs", 24 * scale);
- theme->set_constant("label_valign_fg", "Tabs", 0 * scale);
- theme->set_constant("label_valign_bg", "Tabs", 2 * scale);
theme->set_constant("hseparation", "Tabs", 4 * scale);
// Separators
@@ -745,7 +729,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("separator", "VSeparator", make_stylebox(hseparator_png, 3, 3, 3, 3));
theme->set_icon("close", "Icons", make_icon(icon_close_png));
- theme->set_font("normal", "Fonts", default_font);
+ theme->set_font("normal", "Fonts", Ref<Font>());
theme->set_font("large", "Fonts", large_font);
theme->set_constant("separation", "HSeparator", 4 * scale);
@@ -759,7 +743,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// FileDialog
theme->set_icon("folder", "FileDialog", make_icon(icon_folder_png));
+ theme->set_icon("file", "FileDialog", make_icon(icon_file_png));
theme->set_color("folder_icon_modulate", "FileDialog", Color(1, 1, 1));
+ theme->set_color("file_icon_modulate", "FileDialog", Color(1, 1, 1));
theme->set_color("files_disabled", "FileDialog", Color(0, 0, 0, 0.7));
// ColorPicker
@@ -782,12 +768,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// TooltipPanel
Ref<StyleBoxTexture> style_tt = make_stylebox(tooltip_bg_png, 4, 4, 4, 4);
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++) {
style_tt->set_expand_margin_size((Margin)i, 4 * scale);
+ }
theme->set_stylebox("panel", "TooltipPanel", style_tt);
- theme->set_font("font", "TooltipLabel", default_font);
+ theme->set_font("font", "TooltipLabel", Ref<Font>());
theme->set_color("font_color", "TooltipLabel", Color(0, 0, 0));
theme->set_color("font_color_shadow", "TooltipLabel", Color(0, 0, 0, 0.1));
@@ -800,11 +787,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("focus", "RichTextLabel", focus);
theme->set_stylebox("normal", "RichTextLabel", make_empty_stylebox(0, 0, 0, 0));
- theme->set_font("normal_font", "RichTextLabel", default_font);
- theme->set_font("bold_font", "RichTextLabel", default_font);
- theme->set_font("italics_font", "RichTextLabel", default_font);
- theme->set_font("bold_italics_font", "RichTextLabel", default_font);
- theme->set_font("mono_font", "RichTextLabel", default_font);
+ theme->set_font("normal_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("bold_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("italics_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("bold_italics_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("mono_font", "RichTextLabel", Ref<Font>());
theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1));
theme->set_color("font_color_selected", "RichTextLabel", font_color_selection);
@@ -870,12 +857,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
}
void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
-
Ref<Theme> t;
t.instance();
Ref<StyleBox> default_style;
- Ref<Texture> default_icon;
+ Ref<Texture2D> default_icon;
Ref<Font> default_font;
if (p_font.is_valid()) {
default_font = p_font;
@@ -894,10 +880,9 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
}
void clear_default_theme() {
-
- Theme::set_project_default(NULL);
- Theme::set_default(NULL);
- Theme::set_default_icon(NULL);
- Theme::set_default_style(NULL);
- Theme::set_default_font(NULL);
+ Theme::set_project_default(nullptr);
+ Theme::set_default(nullptr);
+ Theme::set_default_icon(nullptr);
+ Theme::set_default_style(nullptr);
+ Theme::set_default_font(nullptr);
}
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index 1807770ff4..46f89a9b50 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -33,7 +33,7 @@
#include "scene/resources/theme.h"
-void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale);
+void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(bool p_hidpi, Ref<Font> p_font);
void clear_default_theme();
diff --git a/scene/resources/default_theme/icon_file.png b/scene/resources/default_theme/icon_file.png
new file mode 100644
index 0000000000..bb4c361a8d
--- /dev/null
+++ b/scene/resources/default_theme/icon_file.png
Binary files differ
diff --git a/scene/resources/default_theme/make_header.py b/scene/resources/default_theme/make_header.py
index cf0ccf1c3a..efad3b2815 100755
--- a/scene/resources/default_theme/make_header.py
+++ b/scene/resources/default_theme/make_header.py
@@ -13,7 +13,7 @@ os.chdir(os.path.dirname(os.path.realpath(__file__)))
f = open("theme_data.h", "wb")
-f.write(b"// THIS FILE HAS BEEN AUTOGENERATED, DON\'T EDIT!!\n")
+f.write(b"// THIS FILE HAS BEEN AUTOGENERATED, DON'T EDIT!!\n")
# Generate png image block
f.write(b"\n// png image block\n")
@@ -31,17 +31,17 @@ for x in pixmaps:
pngf = open(x, "rb")
b = pngf.read(1)
- while(len(b) == 1):
+ while len(b) == 1:
f.write(hex(ord(b)).encode(enc))
b = pngf.read(1)
- if (len(b) == 1):
+ if len(b) == 1:
f.write(b", ")
f.write(b"\n};\n")
pngf.close()
# Generate shaders block
-f.write(b"\n// shaders block\n");
+f.write(b"\n// shaders block\n")
shaders = glob.glob("*.gsl")
shaders.sort()
@@ -56,15 +56,15 @@ for x in shaders:
sf = open(x, "rb")
b = sf.readline()
- while(b != ""):
- if (b.endswith("\r\n")):
+ while b != "":
+ if b.endswith("\r\n"):
b = b[:-2]
- if (b.endswith("\n")):
+ if b.endswith("\n"):
b = b[:-1]
- s = ' \"' + b
+ s = ' "' + b
f.write(s.encode(enc))
b = sf.readline()
- if (b != ""):
+ if b != "":
f.write(b'"\n')
f.write(b'";\n')
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 0a4e557451..a15efb593a 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -10,6 +10,10 @@ static const unsigned char arrow_right_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char bookmark_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0xa, 0xc0, 0x30, 0xc, 0x3, 0xa5, 0xd0, 0xff, 0x7f, 0x59, 0x1d, 0x8a, 0x42, 0x8, 0x9, 0x95, 0xc9, 0xd2, 0xa1, 0x9a, 0x8c, 0xf1, 0xdd, 0x62, 0x1b, 0x38, 0xc, 0x87, 0x5a, 0x5, 0xae, 0x79, 0xde, 0x2, 0x1, 0x80, 0x94, 0x39, 0x48, 0x76, 0x49, 0x17, 0xa4, 0xf0, 0x24, 0x61, 0x2b, 0x51, 0x8b, 0xfc, 0x82, 0xcf, 0xb, 0x48, 0x7a, 0xdf, 0x75, 0x81, 0xf, 0xe5, 0x29, 0xf7, 0x92, 0x6b, 0x3, 0x1a, 0x1e, 0xda, 0x7c, 0x3d, 0x77, 0x21, 0x7b, 0xa8, 0x74, 0x2e, 0xcb, 0xd, 0xc8, 0x75, 0x13, 0x28, 0x9, 0xed, 0xc2, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char button_disabled_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xc7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xd0, 0x81, 0x66, 0x43, 0x31, 0x14, 0x87, 0xf1, 0xf, 0x5, 0x17, 0xb8, 0x28, 0x2e, 0x8, 0x71, 0xf3, 0x6, 0x19, 0xb6, 0xb9, 0xcb, 0xac, 0x95, 0xa4, 0xb7, 0xad, 0x6a, 0xd5, 0x68, 0x5f, 0xe4, 0x3e, 0x76, 0x1e, 0xe1, 0xbf, 0x21, 0xa6, 0xab, 0xf8, 0x1, 0x7c, 0x9c, 0x73, 0xe, 0xac, 0xe8, 0xe8, 0x19, 0x30, 0x58, 0xc6, 0xca, 0x62, 0x18, 0xe8, 0xe9, 0x58, 0x41, 0xc7, 0x1a, 0x87, 0x27, 0x10, 0x49, 0xe4, 0x5f, 0x89, 0x48, 0xc0, 0xe3, 0x58, 0xd3, 0x41, 0x8f, 0xb, 0xcb, 0xbd, 0x7c, 0xeb, 0xbf, 0x7b, 0x9, 0xb, 0x8e, 0x1e, 0x6, 0xfc, 0xad, 0x64, 0x6d, 0xb5, 0x79, 0xb0, 0x55, 0xd6, 0xad, 0xe0, 0x19, 0xc0, 0x10, 0xae, 0xda, 0x34, 0x5c, 0x45, 0xc0, 0x80, 0x25, 0x5e, 0xf4, 0xd5, 0x70, 0x11, 0x11, 0xb, 0x23, 0xe9, 0xac, 0xcf, 0x86, 0xb3, 0x48, 0x8c, 0x30, 0x92, 0x4f, 0xa, 0xd, 0x27, 0x91, 0x6b, 0x70, 0xd4, 0x47, 0xc3, 0xf1, 0x2f, 0x48, 0x7, 0x4d, 0xd, 0x87, 0x3a, 0xc2, 0x12, 0x67, 0xbd, 0x37, 0xcc, 0x75, 0x49, 0x43, 0xd8, 0xe9, 0xad, 0x61, 0x57, 0xcf, 0x1c, 0xf0, 0xfb, 0x32, 0xe9, 0xf5, 0xc9, 0xa4, 0x7d, 0x7d, 0x54, 0x8f, 0x7b, 0x59, 0xe6, 0x92, 0x14, 0x1f, 0x24, 0xcd, 0x3f, 0x7b, 0x6b, 0xa, 0xe, 0x6a, 0x82, 0x91, 0x45, 0x30, 0xba, 0x1, 0x4a, 0x51, 0xc4, 0x35, 0x1f, 0xe5, 0xa1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
@@ -150,6 +154,10 @@ static const unsigned char icon_color_pick_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xaa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x9d, 0x8e, 0x35, 0x82, 0x2, 0x41, 0x10, 0x45, 0x3b, 0xda, 0x3d, 0xca, 0xba, 0x44, 0x2b, 0x70, 0x9, 0xdc, 0xe1, 0x20, 0xe8, 0x91, 0x90, 0x78, 0x6e, 0x40, 0x4c, 0x82, 0x74, 0xff, 0xc2, 0x9d, 0x18, 0xa7, 0x6, 0x77, 0x7b, 0x23, 0x2d, 0xaf, 0x4c, 0xdc, 0xc, 0xbd, 0x65, 0x1e, 0x84, 0x80, 0x19, 0x55, 0x34, 0x60, 0x3e, 0xd0, 0xea, 0x17, 0x3d, 0x4a, 0xc8, 0x80, 0x1a, 0x60, 0xc2, 0x4f, 0xfd, 0x30, 0xe0, 0x1b, 0x2d, 0x16, 0xab, 0xa7, 0x2c, 0xe, 0x41, 0x68, 0xa5, 0xb9, 0xca, 0x91, 0x16, 0x2e, 0x54, 0xe0, 0x59, 0x54, 0x91, 0xfe, 0xa3, 0x3a, 0xff, 0xce, 0xab, 0x5b, 0xf, 0xa0, 0x4, 0x8f, 0x7b, 0x4c, 0xd3, 0x1b, 0xca, 0x32, 0xcc, 0x55, 0x7a, 0xf4, 0x76, 0x42, 0x2b, 0x97, 0x3e, 0xae, 0xfa, 0xdd, 0xd2, 0xd2, 0x8e, 0x72, 0xe1, 0x83, 0xaf, 0x9f, 0xa9, 0x28, 0x7d, 0x5b, 0xe2, 0x2a, 0xd, 0xc3, 0xa2, 0x78, 0xfe, 0x7d, 0x51, 0xfc, 0x0, 0x8a, 0x41, 0xcb, 0x3d, 0xb2, 0xae, 0x1c, 0xd3, 0xc, 0xa5, 0x30, 0x81, 0xc6, 0xda, 0x29, 0x8e, 0x83, 0x34, 0x25, 0x29, 0x4a, 0x46, 0x71, 0x1f, 0x33, 0xbe, 0x51, 0x89, 0xaf, 0x78, 0xe3, 0x97, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char icon_file_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x2, 0x3, 0x0, 0x0, 0x0, 0x62, 0x9d, 0x17, 0xf2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc3, 0x0, 0x0, 0xe, 0xc3, 0x1, 0xc7, 0x6f, 0xa8, 0x64, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0x9, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0x42, 0xf, 0xc7, 0x49, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x88, 0x95, 0xf0, 0xc6, 0x2a, 0x0, 0x0, 0x0, 0x21, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x0, 0x1, 0xae, 0x55, 0x2d, 0x20, 0xa2, 0x13, 0x44, 0x74, 0x39, 0x80, 0x88, 0x9, 0x40, 0xa2, 0x1, 0xc4, 0x5d, 0xb5, 0x80, 0x68, 0x2, 0x4, 0x0, 0x95, 0x34, 0x18, 0xe4, 0x5e, 0x46, 0xf7, 0x27, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char icon_folder_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x6, 0x78, 0x70, 0xf4, 0xc1, 0x7f, 0x24, 0x78, 0x18, 0x53, 0xc1, 0x7f, 0x54, 0x48, 0x50, 0xc1, 0x43, 0x1b, 0xbc, 0xa, 0x50, 0xad, 0x23, 0xa4, 0xe0, 0xff, 0x70, 0x52, 0x70, 0x18, 0x97, 0xf4, 0xfd, 0x43, 0xd4, 0x88, 0x4a, 0x0, 0x5a, 0xcb, 0x18, 0xab, 0x5e, 0xd9, 0x1a, 0x53, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index d19d82d252..bc983c1d7e 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -28,8 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef FREETYPE_ENABLED
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_FREETYPE_ENABLED
+
#include "dynamic_font.h"
+
#include "core/os/file_access.h"
#include "core/os/os.h"
@@ -43,7 +46,6 @@ bool DynamicFontData::CacheID::operator<(CacheID right) const {
}
Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_cache_id) {
-
if (size_cache.has(p_cache_id)) {
return Ref<DynamicFontAtSize>(size_cache[p_cache_id]);
}
@@ -62,13 +64,11 @@ Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_cach
}
void DynamicFontData::set_font_ptr(const uint8_t *p_font_mem, int p_font_mem_size) {
-
font_mem = p_font_mem;
font_mem_size = p_font_mem_size;
}
void DynamicFontData::set_font_path(const String &p_path) {
-
font_path = p_path;
}
@@ -77,7 +77,6 @@ String DynamicFontData::get_font_path() const {
}
void DynamicFontData::set_force_autohinter(bool p_force) {
-
force_autohinter = p_force;
}
@@ -100,11 +99,10 @@ void DynamicFontData::_bind_methods() {
}
DynamicFontData::DynamicFontData() {
-
antialiased = true;
force_autohinter = false;
hinting = DynamicFontData::HINTING_NORMAL;
- font_mem = NULL;
+ font_mem = nullptr;
font_mem_size = 0;
}
@@ -112,23 +110,20 @@ DynamicFontData::~DynamicFontData() {
}
////////////////////
-HashMap<String, Vector<uint8_t> > DynamicFontAtSize::_fontdata;
+HashMap<String, Vector<uint8_t>> DynamicFontAtSize::_fontdata;
Error DynamicFontAtSize::_load() {
-
int error = FT_Init_FreeType(&library);
ERR_FAIL_COND_V_MSG(error != 0, ERR_CANT_CREATE, "Error initializing FreeType.");
// FT_OPEN_STREAM is extremely slow only on Android.
- if (OS::get_singleton()->get_name() == "Android" && font->font_mem == NULL && font->font_path != String()) {
+ if (OS::get_singleton()->get_name() == "Android" && font->font_mem == nullptr && font->font_path != String()) {
// cache font only once for each font->font_path
if (_fontdata.has(font->font_path)) {
-
font->set_font_ptr(_fontdata[font->font_path].ptr(), _fontdata[font->font_path].size());
} else {
-
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
if (!f) {
FT_Done_FreeType(library);
@@ -145,8 +140,7 @@ Error DynamicFontAtSize::_load() {
}
}
- if (font->font_mem == NULL && font->font_path != String()) {
-
+ if (font->font_mem == nullptr && font->font_path != String()) {
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
if (!f) {
FT_Done_FreeType(library);
@@ -154,7 +148,7 @@ Error DynamicFontAtSize::_load() {
}
memset(&stream, 0, sizeof(FT_StreamRec));
- stream.base = NULL;
+ stream.base = nullptr;
stream.size = f->get_len();
stream.pos = 0;
stream.descriptor.pointer = f;
@@ -167,7 +161,6 @@ Error DynamicFontAtSize::_load() {
fargs.stream = &stream;
error = FT_Open_Face(library, &fargs, 0, &face);
} else if (font->font_mem) {
-
memset(&stream, 0, sizeof(FT_StreamRec));
stream.base = (unsigned char *)font->font_mem;
stream.size = font->font_mem_size;
@@ -189,12 +182,10 @@ Error DynamicFontAtSize::_load() {
//error = FT_New_Face( library, src_path.utf8().get_data(),0,&face );
if (error == FT_Err_Unknown_File_Format) {
-
FT_Done_FreeType(library);
ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "Unknown font format.");
} else if (error) {
-
FT_Done_FreeType(library);
ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "Error loading font.");
}
@@ -218,12 +209,9 @@ Error DynamicFontAtSize::_load() {
ascent = (face->size->metrics.ascender / 64.0) / oversampling * scale_color_font;
descent = (-face->size->metrics.descender / 64.0) / oversampling * scale_color_font;
+ underline_position = -face->underline_position / 64.0 / oversampling * scale_color_font;
+ underline_thickness = face->underline_thickness / 64.0 / oversampling * scale_color_font;
linegap = 0;
- texture_flags = 0;
- if (id.mipmaps)
- texture_flags |= Texture::FLAG_MIPMAPS;
- if (id.filter)
- texture_flags |= Texture::FLAG_FILTER;
valid = true;
return OK;
@@ -232,38 +220,44 @@ Error DynamicFontAtSize::_load() {
float DynamicFontAtSize::font_oversampling = 1.0;
float DynamicFontAtSize::get_height() const {
-
return ascent + descent;
}
float DynamicFontAtSize::get_ascent() const {
-
return ascent;
}
-float DynamicFontAtSize::get_descent() const {
+float DynamicFontAtSize::get_descent() const {
return descent;
}
-const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const {
+float DynamicFontAtSize::get_underline_position() const {
+ return underline_position;
+}
+
+float DynamicFontAtSize::get_underline_thickness() const {
+ return underline_thickness;
+}
+
+const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(char32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
const Character *chr = char_map.getptr(p_char);
- ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(NULL, NULL)));
+ ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(nullptr, nullptr)));
if (!chr->found) {
-
//not found, try in fallbacks
for (int i = 0; i < p_fallbacks.size(); i++) {
-
DynamicFontAtSize *fb = const_cast<DynamicFontAtSize *>(p_fallbacks[i].ptr());
- if (!fb->valid)
+ if (!fb->valid) {
continue;
+ }
fb->_update_char(p_char);
const Character *fallback_chr = fb->char_map.getptr(p_char);
ERR_CONTINUE(!fallback_chr);
- if (!fallback_chr->found)
+ if (!fallback_chr->found) {
continue;
+ }
return Pair<const Character *, DynamicFontAtSize *>(fallback_chr, fb);
}
@@ -271,16 +265,16 @@ const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFon
//not found, try 0xFFFD to display 'not found'.
const_cast<DynamicFontAtSize *>(this)->_update_char(0xFFFD);
chr = char_map.getptr(0xFFFD);
- ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(NULL, NULL)));
+ ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(nullptr, nullptr)));
}
return Pair<const Character *, DynamicFontAtSize *>(chr, const_cast<DynamicFontAtSize *>(this));
}
-Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const {
-
- if (!valid)
+Size2 DynamicFontAtSize::get_char_size(char32_t p_char, char32_t p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
+ if (!valid) {
return Size2(1, 1);
+ }
const_cast<DynamicFontAtSize *>(this)->_update_char(p_char);
Pair<const Character *, DynamicFontAtSize *> char_pair_with_font = _find_char_with_font(p_char, p_fallbacks);
@@ -296,20 +290,25 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V
return ret;
}
-void DynamicFontAtSize::set_texture_flags(uint32_t p_flags) {
+String DynamicFontAtSize::get_available_chars() const {
+ String chars;
- texture_flags = p_flags;
- for (int i = 0; i < textures.size(); i++) {
- Ref<ImageTexture> &tex = textures.write[i].texture;
- if (!tex.is_null())
- tex->set_flags(p_flags);
+ FT_UInt gindex;
+ FT_ULong charcode = FT_Get_First_Char(face, &gindex);
+ while (gindex != 0) {
+ if (charcode != 0) {
+ chars += char32_t(charcode);
+ }
+ charcode = FT_Get_Next_Char(face, charcode, &gindex);
}
-}
-float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only, bool p_outline) const {
+ return chars;
+}
- if (!valid)
+float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const {
+ if (!valid) {
return 0;
+ }
const_cast<DynamicFontAtSize *>(this)->_update_char(p_char);
@@ -348,7 +347,7 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT
modulate.r = modulate.g = modulate.b = 1.0;
}
RID texture = font->textures[ch->texture_idx].texture->get_rid();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), false);
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), RID(), Color(1, 1, 1, 1), false);
}
advance = ch->advance;
@@ -358,20 +357,20 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT
}
unsigned long DynamicFontAtSize::_ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
-
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
if (f->get_position() != offset) {
f->seek(offset);
}
- if (count == 0)
+ if (count == 0) {
return 0;
+ }
return f->get_buffer(buffer, count);
}
-void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) {
+void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) {
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
f->close();
memdelete(f);
@@ -397,27 +396,27 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
int mh = p_height;
for (int i = 0; i < textures.size(); i++) {
-
const CharTexture &ct = textures[i];
- if (ct.texture->get_format() != p_image_format)
+ if (ct.texture->get_format() != p_image_format) {
continue;
+ }
- if (mw > ct.texture_size || mh > ct.texture_size) //too big for this texture
+ if (mw > ct.texture_size || mh > ct.texture_size) { //too big for this texture
continue;
+ }
ret.y = 0x7FFFFFFF;
ret.x = 0;
for (int j = 0; j < ct.texture_size - mw; j++) {
-
int max_y = 0;
for (int k = j; k < j + mw; k++) {
-
int y = ct.offsets[k];
- if (y > max_y)
+ if (y > max_y) {
max_y = y;
+ }
}
if (max_y < ret.y) {
@@ -426,8 +425,9 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
}
}
- if (ret.y == 0x7FFFFFFF || ret.y + mh > ct.texture_size)
+ if (ret.y == 0x7FFFFFFF || ret.y + mh > ct.texture_size) {
continue; //fail, could not fit it here
+ }
ret.index = i;
break;
@@ -439,10 +439,12 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
ret.y = 0;
int texsize = MAX(id.size * oversampling * 8, 256);
- if (mw > texsize)
+ if (mw > texsize) {
texsize = mw; //special case, adapt to it?
- if (mh > texsize)
+ }
+ if (mh > texsize) {
texsize = mh; //special case, adapt to it?
+ }
texsize = next_power_of_2(texsize);
@@ -454,15 +456,16 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
{
//zero texture
- PoolVector<uint8_t>::Write w = tex.imgdata.write();
+ uint8_t *w = tex.imgdata.ptrw();
ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.imgdata.size(), ret);
for (int i = 0; i < texsize * texsize * p_color_size; i++) {
w[i] = 0;
}
}
tex.offsets.resize(texsize);
- for (int i = 0; i < texsize; i++) //zero offsets
+ for (int i = 0; i < texsize; i++) { //zero offsets
tex.offsets.write[i] = 0;
+ }
textures.push_back(tex);
ret.index = textures.size() - 1;
@@ -492,11 +495,10 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
CharTexture &tex = textures.write[tex_pos.index];
{
- PoolVector<uint8_t>::Write wr = tex.imgdata.write();
+ uint8_t *wr = tex.imgdata.ptrw();
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
-
int ofs = ((i + tex_pos.y + rect_margin) * tex.texture_size + j + tex_pos.x + rect_margin) * color_size;
ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), Character::not_found());
switch (bitmap.pixel_mode) {
@@ -528,14 +530,13 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
//blit to image and texture
{
-
Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, require_format, tex.imgdata));
if (tex.texture.is_null()) {
tex.texture.instance();
- tex.texture->create_from_image(img, Texture::FLAG_VIDEO_SURFACE | texture_flags);
+ tex.texture->create_from_image(img);
} else {
- tex.texture->set_data(img); //update
+ tex.texture->update(img); //update
}
}
@@ -559,26 +560,31 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
return chr;
}
-DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_char) {
+DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(char32_t p_char) {
Character ret = Character::not_found();
- if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0)
+ if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0) {
return ret;
+ }
FT_Stroker stroker;
- if (FT_Stroker_New(library, &stroker) != 0)
+ if (FT_Stroker_New(library, &stroker) != 0) {
return ret;
+ }
FT_Stroker_Set(stroker, (int)(id.outline_size * oversampling * 64.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
FT_Glyph glyph;
FT_BitmapGlyph glyph_bitmap;
- if (FT_Get_Glyph(face->glyph, &glyph) != 0)
+ if (FT_Get_Glyph(face->glyph, &glyph) != 0) {
goto cleanup_stroker;
- if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0)
+ }
+ if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) {
goto cleanup_glyph;
- if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1) != 0)
+ }
+ if (FT_Glyph_To_Bitmap(&glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, nullptr, 1) != 0) {
goto cleanup_glyph;
+ }
glyph_bitmap = (FT_BitmapGlyph)glyph;
ret = _bitmap_to_character(glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, glyph->advance.x / 65536.0);
@@ -590,10 +596,10 @@ cleanup_stroker:
return ret;
}
-void DynamicFontAtSize::_update_char(CharType p_char) {
-
- if (char_map.has(p_char))
+void DynamicFontAtSize::_update_char(char32_t p_char) {
+ if (char_map.has(p_char)) {
return;
+ }
_THREAD_SAFE_METHOD_
@@ -630,16 +636,18 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
character = _make_outline_char(p_char);
} else {
error = FT_Render_Glyph(face->glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
- if (!error)
+ if (!error) {
character = _bitmap_to_character(slot->bitmap, slot->bitmap_top, slot->bitmap_left, slot->advance.x / 64.0);
+ }
}
char_map[p_char] = character;
}
void DynamicFontAtSize::update_oversampling() {
- if (oversampling == font_oversampling || !valid)
+ if (oversampling == font_oversampling || !valid) {
return;
+ }
FT_Done_FreeType(library);
textures.clear();
@@ -650,19 +658,16 @@ void DynamicFontAtSize::update_oversampling() {
}
DynamicFontAtSize::DynamicFontAtSize() {
-
valid = false;
rect_margin = 1;
ascent = 1;
descent = 1;
linegap = 1;
- texture_flags = 0;
oversampling = font_oversampling;
scale_color_font = 1;
}
DynamicFontAtSize::~DynamicFontAtSize() {
-
if (valid) {
FT_Done_FreeType(library);
}
@@ -673,7 +678,6 @@ DynamicFontAtSize::~DynamicFontAtSize() {
/////////////////////////
void DynamicFont::_reload_cache() {
-
ERR_FAIL_COND(cache_id.size < 1);
if (!data.is_valid()) {
data_at_size.unref();
@@ -695,8 +699,9 @@ void DynamicFont::_reload_cache() {
for (int i = 0; i < fallbacks.size(); i++) {
fallback_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(cache_id);
- if (outline_cache_id.outline_size > 0)
+ if (outline_cache_id.outline_size > 0) {
fallback_outline_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(outline_cache_id);
+ }
}
emit_changed();
@@ -704,7 +709,6 @@ void DynamicFont::_reload_cache() {
}
void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) {
-
data = p_data;
_reload_cache();
@@ -713,27 +717,26 @@ void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) {
}
Ref<DynamicFontData> DynamicFont::get_font_data() const {
-
return data;
}
void DynamicFont::set_size(int p_size) {
-
- if (cache_id.size == p_size)
+ if (cache_id.size == p_size) {
return;
+ }
cache_id.size = p_size;
outline_cache_id.size = p_size;
_reload_cache();
}
int DynamicFont::get_size() const {
-
return cache_id.size;
}
void DynamicFont::set_outline_size(int p_size) {
- if (outline_cache_id.outline_size == p_size)
+ if (outline_cache_id.outline_size == p_size) {
return;
+ }
ERR_FAIL_COND(p_size < 0 || p_size > UINT8_MAX);
outline_cache_id.outline_size = p_size;
_reload_cache();
@@ -755,60 +758,29 @@ Color DynamicFont::get_outline_color() const {
return outline_color;
}
-bool DynamicFont::get_use_mipmaps() const {
-
- return cache_id.mipmaps;
-}
-
-void DynamicFont::set_use_mipmaps(bool p_enable) {
-
- if (cache_id.mipmaps == p_enable)
- return;
- cache_id.mipmaps = p_enable;
- outline_cache_id.mipmaps = p_enable;
- _reload_cache();
-}
-
-bool DynamicFont::get_use_filter() const {
-
- return cache_id.filter;
-}
-
-void DynamicFont::set_use_filter(bool p_enable) {
-
- if (cache_id.filter == p_enable)
- return;
- cache_id.filter = p_enable;
- outline_cache_id.filter = p_enable;
- _reload_cache();
-}
-
bool DynamicFontData::is_antialiased() const {
-
return antialiased;
}
void DynamicFontData::set_antialiased(bool p_antialiased) {
-
- if (antialiased == p_antialiased)
+ if (antialiased == p_antialiased) {
return;
+ }
antialiased = p_antialiased;
}
DynamicFontData::Hinting DynamicFontData::get_hinting() const {
-
return hinting;
}
void DynamicFontData::set_hinting(Hinting p_hinting) {
-
- if (hinting == p_hinting)
+ if (hinting == p_hinting) {
return;
+ }
hinting = p_hinting;
}
int DynamicFont::get_spacing(int p_type) const {
-
if (p_type == SPACING_TOP) {
return spacing_top;
} else if (p_type == SPACING_BOTTOM) {
@@ -823,7 +795,6 @@ int DynamicFont::get_spacing(int p_type) const {
}
void DynamicFont::set_spacing(int p_type, int p_value) {
-
if (p_type == SPACING_TOP) {
spacing_top = p_value;
} else if (p_type == SPACING_BOTTOM) {
@@ -839,45 +810,80 @@ void DynamicFont::set_spacing(int p_type, int p_value) {
}
float DynamicFont::get_height() const {
-
- if (!data_at_size.is_valid())
+ if (!data_at_size.is_valid()) {
return 1;
+ }
return data_at_size->get_height() + spacing_top + spacing_bottom;
}
float DynamicFont::get_ascent() const {
-
- if (!data_at_size.is_valid())
+ if (!data_at_size.is_valid()) {
return 1;
+ }
return data_at_size->get_ascent() + spacing_top;
}
float DynamicFont::get_descent() const {
-
- if (!data_at_size.is_valid())
+ if (!data_at_size.is_valid()) {
return 1;
+ }
return data_at_size->get_descent() + spacing_bottom;
}
-Size2 DynamicFont::get_char_size(CharType p_char, CharType p_next) const {
+float DynamicFont::get_underline_position() const {
+ if (!data_at_size.is_valid()) {
+ return 2;
+ }
+
+ return data_at_size->get_underline_position();
+}
+
+float DynamicFont::get_underline_thickness() const {
+ if (!data_at_size.is_valid()) {
+ return 1;
+ }
- if (!data_at_size.is_valid())
+ return data_at_size->get_underline_thickness();
+}
+
+Size2 DynamicFont::get_char_size(char32_t p_char, char32_t p_next) const {
+ if (!data_at_size.is_valid()) {
return Size2(1, 1);
+ }
Size2 ret = data_at_size->get_char_size(p_char, p_next, fallback_data_at_size);
- if (p_char == ' ')
+ if (p_char == ' ') {
ret.width += spacing_space + spacing_char;
- else if (p_next)
+ } else if (p_next) {
ret.width += spacing_char;
+ }
return ret;
}
-bool DynamicFont::is_distance_field_hint() const {
+String DynamicFont::get_available_chars() const {
+ if (!data_at_size.is_valid()) {
+ return "";
+ }
+ String chars = data_at_size->get_available_chars();
+
+ for (int i = 0; i < fallback_data_at_size.size(); i++) {
+ String fallback_chars = fallback_data_at_size[i]->get_available_chars();
+ for (int j = 0; j < fallback_chars.length(); j++) {
+ if (chars.find_char(fallback_chars[j]) == -1) {
+ chars += fallback_chars[j];
+ }
+ }
+ }
+
+ return chars;
+}
+
+bool DynamicFont::is_distance_field_hint() const {
return false;
}
@@ -885,13 +891,14 @@ bool DynamicFont::has_outline() const {
return outline_cache_id.outline_size > 0;
}
-float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const {
+float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, bool p_outline) const {
const Ref<DynamicFontAtSize> &font_at_size = p_outline && outline_cache_id.outline_size > 0 ? outline_data_at_size : data_at_size;
- if (!font_at_size.is_valid())
+ if (!font_at_size.is_valid()) {
return 0;
+ }
- const Vector<Ref<DynamicFontAtSize> > &fallbacks = p_outline && outline_cache_id.outline_size > 0 ? fallback_outline_data_at_size : fallback_data_at_size;
+ const Vector<Ref<DynamicFontAtSize>> &fallbacks = p_outline && outline_cache_id.outline_size > 0 ? fallback_outline_data_at_size : fallback_data_at_size;
Color color = p_outline && outline_cache_id.outline_size > 0 ? p_modulate * outline_color : p_modulate;
// If requested outline draw, but no outline is present, simply return advance without drawing anything
@@ -900,7 +907,6 @@ float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_
}
void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) {
-
ERR_FAIL_COND(p_data.is_null());
ERR_FAIL_INDEX(p_idx, fallbacks.size());
fallbacks.write[p_idx] = p_data;
@@ -908,12 +914,12 @@ void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) {
}
void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) {
-
ERR_FAIL_COND(p_data.is_null());
fallbacks.push_back(p_data);
fallback_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(cache_id)); //const..
- if (outline_cache_id.outline_size > 0)
+ if (outline_cache_id.outline_size > 0) {
fallback_outline_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(outline_cache_id));
+ }
_change_notify();
emit_changed();
@@ -923,14 +929,14 @@ void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) {
int DynamicFont::get_fallback_count() const {
return fallbacks.size();
}
-Ref<DynamicFontData> DynamicFont::get_fallback(int p_idx) const {
+Ref<DynamicFontData> DynamicFont::get_fallback(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, fallbacks.size(), Ref<DynamicFontData>());
return fallbacks[p_idx];
}
-void DynamicFont::remove_fallback(int p_idx) {
+void DynamicFont::remove_fallback(int p_idx) {
ERR_FAIL_INDEX(p_idx, fallbacks.size());
fallbacks.remove(p_idx);
fallback_data_at_size.remove(p_idx);
@@ -939,7 +945,6 @@ void DynamicFont::remove_fallback(int p_idx) {
}
bool DynamicFont::_set(const StringName &p_name, const Variant &p_value) {
-
String str = p_name;
if (str.begins_with("fallback/")) {
int idx = str.get_slicec('/', 1).to_int();
@@ -965,7 +970,6 @@ bool DynamicFont::_set(const StringName &p_name, const Variant &p_value) {
}
bool DynamicFont::_get(const StringName &p_name, Variant &r_ret) const {
-
String str = p_name;
if (str.begins_with("fallback/")) {
int idx = str.get_slicec('/', 1).to_int();
@@ -981,8 +985,8 @@ bool DynamicFont::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
-void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const {
+void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < fallbacks.size(); i++) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "fallback/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "DynamicFontData"));
}
@@ -991,10 +995,11 @@ void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const {
}
void DynamicFont::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_font_data", "data"), &DynamicFont::set_font_data);
ClassDB::bind_method(D_METHOD("get_font_data"), &DynamicFont::get_font_data);
+ ClassDB::bind_method(D_METHOD("get_available_chars"), &DynamicFont::get_available_chars);
+
ClassDB::bind_method(D_METHOD("set_size", "data"), &DynamicFont::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &DynamicFont::get_size);
@@ -1004,10 +1009,6 @@ void DynamicFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_outline_color", "color"), &DynamicFont::set_outline_color);
ClassDB::bind_method(D_METHOD("get_outline_color"), &DynamicFont::get_outline_color);
- ClassDB::bind_method(D_METHOD("set_use_mipmaps", "enable"), &DynamicFont::set_use_mipmaps);
- ClassDB::bind_method(D_METHOD("get_use_mipmaps"), &DynamicFont::get_use_mipmaps);
- ClassDB::bind_method(D_METHOD("set_use_filter", "enable"), &DynamicFont::set_use_filter);
- ClassDB::bind_method(D_METHOD("get_use_filter"), &DynamicFont::get_use_filter);
ClassDB::bind_method(D_METHOD("set_spacing", "type", "value"), &DynamicFont::set_spacing);
ClassDB::bind_method(D_METHOD("get_spacing", "type"), &DynamicFont::get_spacing);
@@ -1021,8 +1022,6 @@ void DynamicFont::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,1024,1"), "set_outline_size", "get_outline_size");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_filter"), "set_use_filter", "get_use_filter");
ADD_GROUP("Extra Spacing", "extra_spacing");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_top"), "set_spacing", "get_spacing", SPACING_TOP);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_bottom"), "set_spacing", "get_spacing", SPACING_BOTTOM);
@@ -1037,13 +1036,13 @@ void DynamicFont::_bind_methods() {
BIND_ENUM_CONSTANT(SPACING_SPACE);
}
-Mutex *DynamicFont::dynamic_font_mutex = NULL;
+Mutex DynamicFont::dynamic_font_mutex;
-SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL;
+SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = nullptr;
DynamicFont::DynamicFont() :
font_list(this) {
-
+ valid = false;
cache_id.size = 16;
outline_cache_id.size = 16;
spacing_top = 0;
@@ -1051,69 +1050,56 @@ DynamicFont::DynamicFont() :
spacing_char = 0;
spacing_space = 0;
outline_color = Color(1, 1, 1);
- if (dynamic_font_mutex) {
- dynamic_font_mutex->lock();
- dynamic_fonts->add(&font_list);
- dynamic_font_mutex->unlock();
- }
+
+ MutexLock lock(dynamic_font_mutex);
+ dynamic_fonts->add(&font_list);
}
DynamicFont::~DynamicFont() {
- if (dynamic_font_mutex) {
- dynamic_font_mutex->lock();
- dynamic_fonts->remove(&font_list);
- dynamic_font_mutex->unlock();
- }
+ MutexLock lock(dynamic_font_mutex);
+ dynamic_fonts->remove(&font_list);
}
void DynamicFont::initialize_dynamic_fonts() {
dynamic_fonts = memnew(SelfList<DynamicFont>::List());
- dynamic_font_mutex = Mutex::create();
}
void DynamicFont::finish_dynamic_fonts() {
- memdelete(dynamic_font_mutex);
- dynamic_font_mutex = NULL;
memdelete(dynamic_fonts);
- dynamic_fonts = NULL;
+ dynamic_fonts = nullptr;
}
void DynamicFont::update_oversampling() {
+ Vector<Ref<DynamicFont>> changed;
+ {
+ MutexLock lock(dynamic_font_mutex);
- Vector<Ref<DynamicFont> > changed;
-
- if (dynamic_font_mutex)
- dynamic_font_mutex->lock();
-
- SelfList<DynamicFont> *E = dynamic_fonts->first();
- while (E) {
-
- if (E->self()->data_at_size.is_valid()) {
- E->self()->data_at_size->update_oversampling();
+ SelfList<DynamicFont> *E = dynamic_fonts->first();
+ while (E) {
+ if (E->self()->data_at_size.is_valid()) {
+ E->self()->data_at_size->update_oversampling();
- if (E->self()->outline_data_at_size.is_valid()) {
- E->self()->outline_data_at_size->update_oversampling();
- }
+ if (E->self()->outline_data_at_size.is_valid()) {
+ E->self()->outline_data_at_size->update_oversampling();
+ }
- for (int i = 0; i < E->self()->fallback_data_at_size.size(); i++) {
- if (E->self()->fallback_data_at_size[i].is_valid()) {
- E->self()->fallback_data_at_size.write[i]->update_oversampling();
+ for (int i = 0; i < E->self()->fallback_data_at_size.size(); i++) {
+ if (E->self()->fallback_data_at_size[i].is_valid()) {
+ E->self()->fallback_data_at_size.write[i]->update_oversampling();
- if (E->self()->has_outline() && E->self()->fallback_outline_data_at_size[i].is_valid()) {
- E->self()->fallback_outline_data_at_size.write[i]->update_oversampling();
+ if (E->self()->has_outline() && E->self()->fallback_outline_data_at_size[i].is_valid()) {
+ E->self()->fallback_outline_data_at_size.write[i]->update_oversampling();
+ }
}
}
+
+ changed.push_back(Ref<DynamicFont>(E->self()));
}
- changed.push_back(Ref<DynamicFont>(E->self()));
+ E = E->next();
}
-
- E = E->next();
}
- if (dynamic_font_mutex)
- dynamic_font_mutex->unlock();
-
for (int i = 0; i < changed.size(); i++) {
changed.write[i]->emit_changed();
}
@@ -1121,37 +1107,36 @@ void DynamicFont::update_oversampling() {
/////////////////////////
-RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error) {
-
- if (r_error)
+RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
Ref<DynamicFontData> dfont;
dfont.instance();
dfont->set_font_path(p_path);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return dfont;
}
void ResourceFormatLoaderDynamicFont::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("ttf");
p_extensions->push_back("otf");
}
bool ResourceFormatLoaderDynamicFont::handles_type(const String &p_type) const {
-
return (p_type == "DynamicFontData");
}
String ResourceFormatLoaderDynamicFont::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "ttf" || el == "otf")
+ if (el == "ttf" || el == "otf") {
return "DynamicFontData";
+ }
return "";
}
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index 2dafd3ce4f..a881e21da8 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -31,7 +31,9 @@
#ifndef DYNAMIC_FONT_H
#define DYNAMIC_FONT_H
-#ifdef FREETYPE_ENABLED
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_FREETYPE_ENABLED
+
#include "core/io/resource_loader.h"
#include "core/os/mutex.h"
#include "core/os/thread_safe.h"
@@ -45,7 +47,6 @@ class DynamicFontAtSize;
class DynamicFont;
class DynamicFontData : public Resource {
-
GDCLASS(DynamicFontData, Resource);
public:
@@ -54,9 +55,7 @@ public:
struct {
uint32_t size : 16;
uint32_t outline_size : 8;
- uint32_t mipmaps : 1;
- uint32_t filter : 1;
- uint32_t unused : 6;
+ uint32_t unused : 8;
};
uint32_t key;
};
@@ -109,7 +108,6 @@ public:
VARIANT_ENUM_CAST(DynamicFontData::Hinting);
class DynamicFontAtSize : public Reference {
-
GDCLASS(DynamicFontAtSize, Reference);
_THREAD_SAFE_CLASS_
@@ -124,14 +122,13 @@ class DynamicFontAtSize : public Reference {
float rect_margin;
float oversampling;
float scale_color_font;
-
- uint32_t texture_flags;
+ float underline_position;
+ float underline_thickness;
bool valid;
struct CharTexture {
-
- PoolVector<uint8_t> imgdata;
+ Vector<uint8_t> imgdata;
int texture_size;
Vector<int> offsets;
Ref<ImageTexture> texture;
@@ -140,7 +137,6 @@ class DynamicFontAtSize : public Reference {
Vector<CharTexture> textures;
struct Character {
-
bool found;
int texture_idx;
Rect2 rect;
@@ -163,23 +159,23 @@ class DynamicFontAtSize : public Reference {
int y;
};
- const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const;
- Character _make_outline_char(CharType p_char);
+ const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(char32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
+ Character _make_outline_char(char32_t p_char);
TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height);
Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance);
static unsigned long _ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count);
static void _ft_stream_close(FT_Stream stream);
- HashMap<CharType, Character> char_map;
+ HashMap<char32_t, Character> char_map;
- _FORCE_INLINE_ void _update_char(CharType p_char);
+ _FORCE_INLINE_ void _update_char(char32_t p_char);
friend class DynamicFontData;
Ref<DynamicFontData> font;
DynamicFontData::CacheID id;
- static HashMap<String, Vector<uint8_t> > _fontdata;
+ static HashMap<String, Vector<uint8_t>> _fontdata;
Error _load();
public:
@@ -189,10 +185,13 @@ public:
float get_ascent() const;
float get_descent() const;
+ float get_underline_position() const;
+ float get_underline_thickness() const;
- Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const;
+ Size2 get_char_size(char32_t p_char, char32_t p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
+ String get_available_chars() const;
- float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const;
+ float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const;
void set_texture_flags(uint32_t p_flags);
void update_oversampling();
@@ -204,7 +203,6 @@ public:
///////////////
class DynamicFont : public Font {
-
GDCLASS(DynamicFont, Font);
public:
@@ -220,9 +218,9 @@ private:
Ref<DynamicFontAtSize> data_at_size;
Ref<DynamicFontAtSize> outline_data_at_size;
- Vector<Ref<DynamicFontData> > fallbacks;
- Vector<Ref<DynamicFontAtSize> > fallback_data_at_size;
- Vector<Ref<DynamicFontAtSize> > fallback_outline_data_at_size;
+ Vector<Ref<DynamicFontData>> fallbacks;
+ Vector<Ref<DynamicFontAtSize>> fallback_data_at_size;
+ Vector<Ref<DynamicFontAtSize>> fallback_outline_data_at_size;
DynamicFontData::CacheID cache_id;
DynamicFontData::CacheID outline_cache_id;
@@ -272,22 +270,25 @@ public:
Ref<DynamicFontData> get_fallback(int p_idx) const;
void remove_fallback(int p_idx);
- virtual float get_height() const;
+ virtual float get_height() const override;
- virtual float get_ascent() const;
- virtual float get_descent() const;
+ virtual float get_ascent() const override;
+ virtual float get_descent() const override;
+ virtual float get_underline_position() const override;
+ virtual float get_underline_thickness() const override;
- virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const;
+ virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const override;
+ String get_available_chars() const;
- virtual bool is_distance_field_hint() const;
+ virtual bool is_distance_field_hint() const override;
- virtual bool has_outline() const;
+ virtual bool has_outline() const override;
- virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const;
+ virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override;
SelfList<DynamicFont> font_list;
- static Mutex *dynamic_font_mutex;
+ static Mutex dynamic_font_mutex;
static SelfList<DynamicFont>::List *dynamic_fonts;
static void initialize_dynamic_fonts();
@@ -304,7 +305,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType);
class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 7597cd636e..ee8e63266d 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -29,1390 +29,1318 @@
/*************************************************************************/
#include "environment.h"
+
#include "core/project_settings.h"
-#include "servers/visual_server.h"
+#include "servers/rendering_server.h"
#include "texture.h"
RID Environment::get_rid() const {
-
return environment;
}
-void Environment::set_background(BGMode p_bg) {
+// Background
+void Environment::set_background(BGMode p_bg) {
bg_mode = p_bg;
- VS::get_singleton()->environment_set_background(environment, VS::EnvironmentBG(p_bg));
+ RS::get_singleton()->environment_set_background(environment, RS::EnvironmentBG(p_bg));
_change_notify();
}
-void Environment::set_sky(const Ref<Sky> &p_sky) {
+Environment::BGMode Environment::get_background() const {
+ return bg_mode;
+}
+void Environment::set_sky(const Ref<Sky> &p_sky) {
bg_sky = p_sky;
-
RID sb_rid;
- if (bg_sky.is_valid())
+ if (bg_sky.is_valid()) {
sb_rid = bg_sky->get_rid();
+ }
+ RS::get_singleton()->environment_set_sky(environment, sb_rid);
+}
- VS::get_singleton()->environment_set_sky(environment, sb_rid);
+Ref<Sky> Environment::get_sky() const {
+ return bg_sky;
}
void Environment::set_sky_custom_fov(float p_scale) {
-
bg_sky_custom_fov = p_scale;
- VS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale);
+ RS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale);
}
-void Environment::set_sky_orientation(const Basis &p_orientation) {
- bg_sky_orientation = p_orientation;
- _change_notify("background_sky_rotation");
- _change_notify("background_sky_rotation_degrees");
- VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation);
+float Environment::get_sky_custom_fov() const {
+ return bg_sky_custom_fov;
}
-void Environment::set_sky_rotation(const Vector3 &p_euler_rad) {
- bg_sky_orientation.set_euler(p_euler_rad);
- _change_notify("background_sky_orientation");
- _change_notify("background_sky_rotation_degrees");
- VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation);
+void Environment::set_sky_rotation(const Vector3 &p_rotation) {
+ bg_sky_rotation = p_rotation;
+ RS::get_singleton()->environment_set_sky_orientation(environment, Basis(p_rotation));
}
-void Environment::set_sky_rotation_degrees(const Vector3 &p_euler_deg) {
- set_sky_rotation(p_euler_deg * Math_PI / 180.0);
- _change_notify("background_sky_rotation");
+Vector3 Environment::get_sky_rotation() const {
+ return bg_sky_rotation;
}
-void Environment::set_bg_color(const Color &p_color) {
+void Environment::set_bg_color(const Color &p_color) {
bg_color = p_color;
- VS::get_singleton()->environment_set_bg_color(environment, p_color);
+ RS::get_singleton()->environment_set_bg_color(environment, p_color);
}
-void Environment::set_bg_energy(float p_energy) {
- bg_energy = p_energy;
- VS::get_singleton()->environment_set_bg_energy(environment, p_energy);
+Color Environment::get_bg_color() const {
+ return bg_color;
}
-void Environment::set_canvas_max_layer(int p_max_layer) {
- bg_canvas_max_layer = p_max_layer;
- VS::get_singleton()->environment_set_canvas_max_layer(environment, p_max_layer);
+void Environment::set_bg_energy(float p_energy) {
+ bg_energy = p_energy;
+ RS::get_singleton()->environment_set_bg_energy(environment, p_energy);
}
-void Environment::set_ambient_light_color(const Color &p_color) {
- ambient_color = p_color;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
+float Environment::get_bg_energy() const {
+ return bg_energy;
}
-void Environment::set_ambient_light_energy(float p_energy) {
- ambient_energy = p_energy;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
+void Environment::set_canvas_max_layer(int p_max_layer) {
+ bg_canvas_max_layer = p_max_layer;
+ RS::get_singleton()->environment_set_canvas_max_layer(environment, p_max_layer);
}
-void Environment::set_ambient_light_sky_contribution(float p_energy) {
- ambient_sky_contribution = p_energy;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
+int Environment::get_canvas_max_layer() const {
+ return bg_canvas_max_layer;
}
-void Environment::set_camera_feed_id(int p_camera_feed_id) {
- camera_feed_id = p_camera_feed_id;
- VS::get_singleton()->environment_set_camera_feed_id(environment, camera_feed_id);
-};
-
-Environment::BGMode Environment::get_background() const {
-
- return bg_mode;
+void Environment::set_camera_feed_id(int p_id) {
+ bg_camera_feed_id = p_id;
+// FIXME: Disabled during Vulkan refactoring, should be ported.
+#if 0
+ RS::get_singleton()->environment_set_camera_feed_id(environment, camera_feed_id);
+#endif
}
-Ref<Sky> Environment::get_sky() const {
- return bg_sky;
+int Environment::get_camera_feed_id() const {
+ return bg_camera_feed_id;
}
-float Environment::get_sky_custom_fov() const {
+// Ambient light
- return bg_sky_custom_fov;
+void Environment::set_ambient_light_color(const Color &p_color) {
+ ambient_color = p_color;
+ _update_ambient_light();
}
-Basis Environment::get_sky_orientation() const {
-
- return bg_sky_orientation;
+Color Environment::get_ambient_light_color() const {
+ return ambient_color;
}
-Vector3 Environment::get_sky_rotation() const {
-
- // should we cache this? maybe overkill
- return bg_sky_orientation.get_euler();
+void Environment::set_ambient_source(AmbientSource p_source) {
+ ambient_source = p_source;
+ _update_ambient_light();
+ _change_notify();
}
-Vector3 Environment::get_sky_rotation_degrees() const {
+Environment::AmbientSource Environment::get_ambient_source() const {
+ return ambient_source;
+}
- return get_sky_rotation() * 180.0 / Math_PI;
+void Environment::set_ambient_light_energy(float p_energy) {
+ ambient_energy = p_energy;
+ _update_ambient_light();
}
-Color Environment::get_bg_color() const {
+float Environment::get_ambient_light_energy() const {
+ return ambient_energy;
+}
- return bg_color;
+void Environment::set_ambient_light_sky_contribution(float p_ratio) {
+ ambient_sky_contribution = p_ratio;
+ _update_ambient_light();
}
-float Environment::get_bg_energy() const {
- return bg_energy;
+float Environment::get_ambient_light_sky_contribution() const {
+ return ambient_sky_contribution;
}
-int Environment::get_canvas_max_layer() const {
- return bg_canvas_max_layer;
+void Environment::set_reflection_source(ReflectionSource p_source) {
+ reflection_source = p_source;
+ _update_ambient_light();
+ _change_notify();
}
-Color Environment::get_ambient_light_color() const {
- return ambient_color;
+Environment::ReflectionSource Environment::get_reflection_source() const {
+ return reflection_source;
}
-float Environment::get_ambient_light_energy() const {
- return ambient_energy;
+void Environment::set_ao_color(const Color &p_color) {
+ ao_color = p_color;
+ _update_ambient_light();
}
-float Environment::get_ambient_light_sky_contribution() const {
- return ambient_sky_contribution;
+Color Environment::get_ao_color() const {
+ return ao_color;
}
-int Environment::get_camera_feed_id(void) const {
- return camera_feed_id;
+void Environment::_update_ambient_light() {
+ RS::get_singleton()->environment_set_ambient_light(
+ environment,
+ ambient_color,
+ RS::EnvironmentAmbientSource(ambient_source),
+ ambient_energy,
+ ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source),
+ ao_color);
}
-void Environment::set_tonemapper(ToneMapper p_tone_mapper) {
+// Tonemap
+void Environment::set_tonemapper(ToneMapper p_tone_mapper) {
tone_mapper = p_tone_mapper;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+ _update_tonemap();
}
Environment::ToneMapper Environment::get_tonemapper() const {
-
return tone_mapper;
}
void Environment::set_tonemap_exposure(float p_exposure) {
-
tonemap_exposure = p_exposure;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+ _update_tonemap();
}
float Environment::get_tonemap_exposure() const {
-
return tonemap_exposure;
}
void Environment::set_tonemap_white(float p_white) {
-
tonemap_white = p_white;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+ _update_tonemap();
}
-float Environment::get_tonemap_white() const {
+float Environment::get_tonemap_white() const {
return tonemap_white;
}
-void Environment::set_tonemap_auto_exposure(bool p_enabled) {
-
- tonemap_auto_exposure = p_enabled;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+void Environment::set_tonemap_auto_exposure_enabled(bool p_enabled) {
+ tonemap_auto_exposure_enabled = p_enabled;
+ _update_tonemap();
_change_notify();
}
-bool Environment::get_tonemap_auto_exposure() const {
- return tonemap_auto_exposure;
+bool Environment::is_tonemap_auto_exposure_enabled() const {
+ return tonemap_auto_exposure_enabled;
}
-void Environment::set_tonemap_auto_exposure_max(float p_auto_exposure_max) {
-
- tonemap_auto_exposure_max = p_auto_exposure_max;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+void Environment::set_tonemap_auto_exposure_min(float p_auto_exposure_min) {
+ tonemap_auto_exposure_min = p_auto_exposure_min;
+ _update_tonemap();
}
-float Environment::get_tonemap_auto_exposure_max() const {
- return tonemap_auto_exposure_max;
+float Environment::get_tonemap_auto_exposure_min() const {
+ return tonemap_auto_exposure_min;
}
-void Environment::set_tonemap_auto_exposure_min(float p_auto_exposure_min) {
-
- tonemap_auto_exposure_min = p_auto_exposure_min;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+void Environment::set_tonemap_auto_exposure_max(float p_auto_exposure_max) {
+ tonemap_auto_exposure_max = p_auto_exposure_max;
+ _update_tonemap();
}
-float Environment::get_tonemap_auto_exposure_min() const {
- return tonemap_auto_exposure_min;
+float Environment::get_tonemap_auto_exposure_max() const {
+ return tonemap_auto_exposure_max;
}
void Environment::set_tonemap_auto_exposure_speed(float p_auto_exposure_speed) {
-
tonemap_auto_exposure_speed = p_auto_exposure_speed;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+ _update_tonemap();
}
-float Environment::get_tonemap_auto_exposure_speed() const {
+float Environment::get_tonemap_auto_exposure_speed() const {
return tonemap_auto_exposure_speed;
}
void Environment::set_tonemap_auto_exposure_grey(float p_auto_exposure_grey) {
-
tonemap_auto_exposure_grey = p_auto_exposure_grey;
- VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+ _update_tonemap();
}
-float Environment::get_tonemap_auto_exposure_grey() const {
+float Environment::get_tonemap_auto_exposure_grey() const {
return tonemap_auto_exposure_grey;
}
-void Environment::set_adjustment_enable(bool p_enable) {
-
- adjustment_enabled = p_enable;
- VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
- _change_notify();
-}
-
-bool Environment::is_adjustment_enabled() const {
-
- return adjustment_enabled;
-}
-
-void Environment::set_adjustment_brightness(float p_brightness) {
-
- adjustment_brightness = p_brightness;
- VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
-}
-float Environment::get_adjustment_brightness() const {
-
- return adjustment_brightness;
-}
-
-void Environment::set_adjustment_contrast(float p_contrast) {
-
- adjustment_contrast = p_contrast;
- VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
-}
-float Environment::get_adjustment_contrast() const {
-
- return adjustment_contrast;
-}
-
-void Environment::set_adjustment_saturation(float p_saturation) {
-
- adjustment_saturation = p_saturation;
- VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
-}
-float Environment::get_adjustment_saturation() const {
-
- return adjustment_saturation;
+void Environment::_update_tonemap() {
+ RS::get_singleton()->environment_set_tonemap(
+ environment,
+ RS::EnvironmentToneMapper(tone_mapper),
+ tonemap_exposure,
+ tonemap_white,
+ tonemap_auto_exposure_enabled,
+ tonemap_auto_exposure_min,
+ tonemap_auto_exposure_max,
+ tonemap_auto_exposure_speed,
+ tonemap_auto_exposure_grey);
}
-void Environment::set_adjustment_color_correction(const Ref<Texture> &p_ramp) {
+// SSR
- adjustment_color_correction = p_ramp;
- VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
-}
-Ref<Texture> Environment::get_adjustment_color_correction() const {
-
- return adjustment_color_correction;
-}
-
-void Environment::_validate_property(PropertyInfo &property) const {
-
- if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "background_sky_orientation" || property.name == "background_sky_rotation" || property.name == "background_sky_rotation_degrees" || property.name == "ambient_light/sky_contribution") {
- if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
- }
- }
-
- if (property.name == "background_color") {
- if (bg_mode != BG_COLOR && bg_mode != BG_COLOR_SKY) {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
- }
- }
-
- if (property.name == "background_canvas_max_layer") {
- if (bg_mode != BG_CANVAS) {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
- }
- }
-
- if (property.name == "background_camera_feed_id") {
- if (bg_mode != BG_CAMERA_FEED) {
- property.usage = PROPERTY_USAGE_NOEDITOR;
- }
- }
-
- static const char *hide_prefixes[] = {
- "fog_",
- "auto_exposure_",
- "ss_reflections_",
- "ssao_",
- "dof_blur_far_",
- "dof_blur_near_",
- "glow_",
- "adjustment_",
- NULL
-
- };
-
- static const char *high_end_prefixes[] = {
- "auto_exposure_",
- "tonemap_",
- "ss_reflections_",
- "ssao_",
- NULL
-
- };
-
- const char **prefixes = hide_prefixes;
- while (*prefixes) {
- String prefix = String(*prefixes);
-
- String enabled = prefix + "enabled";
- if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
- return;
- }
-
- prefixes++;
- }
-
- if (VisualServer::get_singleton()->is_low_end()) {
- prefixes = high_end_prefixes;
- while (*prefixes) {
- String prefix = String(*prefixes);
-
- if (property.name.begins_with(prefix)) {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
- return;
- }
-
- prefixes++;
- }
- }
-}
-
-void Environment::set_ssr_enabled(bool p_enable) {
-
- ssr_enabled = p_enable;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
+void Environment::set_ssr_enabled(bool p_enabled) {
+ ssr_enabled = p_enabled;
+ _update_ssr();
_change_notify();
}
bool Environment::is_ssr_enabled() const {
-
return ssr_enabled;
}
void Environment::set_ssr_max_steps(int p_steps) {
-
ssr_max_steps = p_steps;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
+ _update_ssr();
}
-int Environment::get_ssr_max_steps() const {
+int Environment::get_ssr_max_steps() const {
return ssr_max_steps;
}
void Environment::set_ssr_fade_in(float p_fade_in) {
-
ssr_fade_in = p_fade_in;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
+ _update_ssr();
}
-float Environment::get_ssr_fade_in() const {
+float Environment::get_ssr_fade_in() const {
return ssr_fade_in;
}
void Environment::set_ssr_fade_out(float p_fade_out) {
-
ssr_fade_out = p_fade_out;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
+ _update_ssr();
}
-float Environment::get_ssr_fade_out() const {
+float Environment::get_ssr_fade_out() const {
return ssr_fade_out;
}
void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) {
-
ssr_depth_tolerance = p_depth_tolerance;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
+ _update_ssr();
}
-float Environment::get_ssr_depth_tolerance() const {
+float Environment::get_ssr_depth_tolerance() const {
return ssr_depth_tolerance;
}
-void Environment::set_ssr_rough(bool p_enable) {
-
- ssr_roughness = p_enable;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
+void Environment::_update_ssr() {
+ RS::get_singleton()->environment_set_ssr(
+ environment,
+ ssr_enabled,
+ ssr_max_steps,
+ ssr_fade_in,
+ ssr_fade_out,
+ ssr_depth_tolerance);
}
-bool Environment::is_ssr_rough() const {
- return ssr_roughness;
-}
+// SSAO
-void Environment::set_ssao_enabled(bool p_enable) {
-
- ssao_enabled = p_enable;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+void Environment::set_ssao_enabled(bool p_enabled) {
+ ssao_enabled = p_enabled;
+ _update_ssao();
_change_notify();
}
bool Environment::is_ssao_enabled() const {
-
return ssao_enabled;
}
void Environment::set_ssao_radius(float p_radius) {
-
ssao_radius = p_radius;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ _update_ssao();
}
-float Environment::get_ssao_radius() const {
+float Environment::get_ssao_radius() const {
return ssao_radius;
}
void Environment::set_ssao_intensity(float p_intensity) {
-
ssao_intensity = p_intensity;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ _update_ssao();
}
float Environment::get_ssao_intensity() const {
-
return ssao_intensity;
}
-void Environment::set_ssao_radius2(float p_radius) {
+void Environment::set_ssao_bias(float p_bias) {
+ ssao_bias = p_bias;
+ _update_ssao();
+}
- ssao_radius2 = p_radius;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+float Environment::get_ssao_bias() const {
+ return ssao_bias;
}
-float Environment::get_ssao_radius2() const {
- return ssao_radius2;
+void Environment::set_ssao_direct_light_affect(float p_direct_light_affect) {
+ ssao_direct_light_affect = p_direct_light_affect;
+ _update_ssao();
}
-void Environment::set_ssao_intensity2(float p_intensity) {
+float Environment::get_ssao_direct_light_affect() const {
+ return ssao_direct_light_affect;
+}
- ssao_intensity2 = p_intensity;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+void Environment::set_ssao_ao_channel_affect(float p_ao_channel_affect) {
+ ssao_ao_channel_affect = p_ao_channel_affect;
+ _update_ssao();
}
-float Environment::get_ssao_intensity2() const {
- return ssao_intensity2;
+float Environment::get_ssao_ao_channel_affect() const {
+ return ssao_ao_channel_affect;
}
-void Environment::set_ssao_bias(float p_bias) {
+void Environment::set_ssao_blur(SSAOBlur p_blur) {
+ ssao_blur = p_blur;
+ _update_ssao();
+}
- ssao_bias = p_bias;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+Environment::SSAOBlur Environment::get_ssao_blur() const {
+ return ssao_blur;
}
-float Environment::get_ssao_bias() const {
- return ssao_bias;
+void Environment::set_ssao_edge_sharpness(float p_edge_sharpness) {
+ ssao_edge_sharpness = p_edge_sharpness;
+ _update_ssao();
}
-void Environment::set_ssao_direct_light_affect(float p_direct_light_affect) {
+float Environment::get_ssao_edge_sharpness() const {
+ return ssao_edge_sharpness;
+}
- ssao_direct_light_affect = p_direct_light_affect;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+void Environment::_update_ssao() {
+ RS::get_singleton()->environment_set_ssao(
+ environment,
+ ssao_enabled,
+ ssao_radius,
+ ssao_intensity,
+ ssao_bias,
+ ssao_direct_light_affect,
+ ssao_ao_channel_affect,
+ RS::EnvironmentSSAOBlur(ssao_blur),
+ ssao_edge_sharpness);
}
-float Environment::get_ssao_direct_light_affect() const {
- return ssao_direct_light_affect;
+// SDFGI
+
+void Environment::set_sdfgi_enabled(bool p_enabled) {
+ sdfgi_enabled = p_enabled;
+ _update_sdfgi();
}
-void Environment::set_ssao_ao_channel_affect(float p_ao_channel_affect) {
+bool Environment::is_sdfgi_enabled() const {
+ return sdfgi_enabled;
+}
- ssao_ao_channel_affect = p_ao_channel_affect;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+void Environment::set_sdfgi_cascades(SDFGICascades p_cascades) {
+ sdfgi_cascades = p_cascades;
+ _update_sdfgi();
}
-float Environment::get_ssao_ao_channel_affect() const {
- return ssao_ao_channel_affect;
+Environment::SDFGICascades Environment::get_sdfgi_cascades() const {
+ return sdfgi_cascades;
}
-void Environment::set_ssao_color(const Color &p_color) {
+void Environment::set_sdfgi_min_cell_size(float p_size) {
+ sdfgi_min_cell_size = p_size;
+ _change_notify("sdfgi_max_distance");
+ _change_notify("sdfgi_cascade0_distance");
+ _update_sdfgi();
+}
- ssao_color = p_color;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+float Environment::get_sdfgi_min_cell_size() const {
+ return sdfgi_min_cell_size;
}
-Color Environment::get_ssao_color() const {
+void Environment::set_sdfgi_max_distance(float p_distance) {
+ p_distance /= 64.0;
+ int cc[3] = { 4, 6, 8 };
+ int cascades = cc[sdfgi_cascades];
+ for (int i = 0; i < cascades; i++) {
+ p_distance *= 0.5; //halve for each cascade
+ }
+ sdfgi_min_cell_size = p_distance;
+ _change_notify("sdfgi_min_cell_size");
+ _change_notify("sdfgi_cascade0_distance");
+ _update_sdfgi();
+}
+
+float Environment::get_sdfgi_max_distance() const {
+ float md = sdfgi_min_cell_size;
+ md *= 64.0;
+ int cc[3] = { 4, 6, 8 };
+ int cascades = cc[sdfgi_cascades];
+ for (int i = 0; i < cascades; i++) {
+ md *= 2.0;
+ }
+ return md;
+}
- return ssao_color;
+void Environment::set_sdfgi_cascade0_distance(float p_distance) {
+ sdfgi_min_cell_size = p_distance / 64.0;
+ _change_notify("sdfgi_min_cell_size");
+ _change_notify("sdfgi_max_distance");
+ _update_sdfgi();
}
-void Environment::set_ssao_blur(SSAOBlur p_blur) {
+float Environment::get_sdfgi_cascade0_distance() const {
+ return sdfgi_min_cell_size * 64.0;
+}
- ssao_blur = p_blur;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+void Environment::set_sdfgi_y_scale(SDFGIYScale p_y_scale) {
+ sdfgi_y_scale = p_y_scale;
+ _update_sdfgi();
}
-Environment::SSAOBlur Environment::get_ssao_blur() const {
- return ssao_blur;
+Environment::SDFGIYScale Environment::get_sdfgi_y_scale() const {
+ return sdfgi_y_scale;
}
-void Environment::set_ssao_quality(SSAOQuality p_quality) {
+void Environment::set_sdfgi_use_occlusion(bool p_enabled) {
+ sdfgi_use_occlusion = p_enabled;
+ _update_sdfgi();
+}
- ssao_quality = p_quality;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+bool Environment::is_sdfgi_using_occlusion() const {
+ return sdfgi_use_occlusion;
}
-Environment::SSAOQuality Environment::get_ssao_quality() const {
+void Environment::set_sdfgi_use_multi_bounce(bool p_enabled) {
+ sdfgi_use_multibounce = p_enabled;
+ _update_sdfgi();
+}
- return ssao_quality;
+bool Environment::is_sdfgi_using_multi_bounce() const {
+ return sdfgi_use_multibounce;
}
-void Environment::set_ssao_edge_sharpness(float p_edge_sharpness) {
+void Environment::set_sdfgi_read_sky_light(bool p_enabled) {
+ sdfgi_read_sky_light = p_enabled;
+ _update_sdfgi();
+}
- ssao_edge_sharpness = p_edge_sharpness;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+bool Environment::is_sdfgi_reading_sky_light() const {
+ return sdfgi_read_sky_light;
}
-float Environment::get_ssao_edge_sharpness() const {
+void Environment::set_sdfgi_energy(float p_energy) {
+ sdfgi_energy = p_energy;
+ _update_sdfgi();
+}
- return ssao_edge_sharpness;
+float Environment::get_sdfgi_energy() const {
+ return sdfgi_energy;
}
-void Environment::set_glow_enabled(bool p_enabled) {
+void Environment::set_sdfgi_normal_bias(float p_bias) {
+ sdfgi_normal_bias = p_bias;
+ _update_sdfgi();
+}
+
+float Environment::get_sdfgi_normal_bias() const {
+ return sdfgi_normal_bias;
+}
+
+void Environment::set_sdfgi_probe_bias(float p_bias) {
+ sdfgi_probe_bias = p_bias;
+ _update_sdfgi();
+}
+
+float Environment::get_sdfgi_probe_bias() const {
+ return sdfgi_probe_bias;
+}
+
+void Environment::_update_sdfgi() {
+ RS::get_singleton()->environment_set_sdfgi(
+ environment,
+ sdfgi_enabled,
+ RS::EnvironmentSDFGICascades(sdfgi_cascades),
+ sdfgi_min_cell_size,
+ RS::EnvironmentSDFGIYScale(sdfgi_y_scale),
+ sdfgi_use_occlusion,
+ sdfgi_use_multibounce,
+ sdfgi_read_sky_light,
+ sdfgi_energy,
+ sdfgi_normal_bias,
+ sdfgi_probe_bias);
+}
+
+// Glow
+void Environment::set_glow_enabled(bool p_enabled) {
glow_enabled = p_enabled;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _update_glow();
_change_notify();
}
bool Environment::is_glow_enabled() const {
-
return glow_enabled;
}
-void Environment::set_glow_level(int p_level, bool p_enabled) {
-
- ERR_FAIL_INDEX(p_level, VS::MAX_GLOW_LEVELS);
+void Environment::set_glow_level_enabled(int p_level, bool p_enabled) {
+ ERR_FAIL_INDEX(p_level, RS::MAX_GLOW_LEVELS);
- if (p_enabled)
+ if (p_enabled) {
glow_levels |= (1 << p_level);
- else
+ } else {
glow_levels &= ~(1 << p_level);
+ }
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _update_glow();
}
-bool Environment::is_glow_level_enabled(int p_level) const {
- ERR_FAIL_INDEX_V(p_level, VS::MAX_GLOW_LEVELS, false);
+bool Environment::is_glow_level_enabled(int p_level) const {
+ ERR_FAIL_INDEX_V(p_level, RS::MAX_GLOW_LEVELS, false);
return glow_levels & (1 << p_level);
}
void Environment::set_glow_intensity(float p_intensity) {
-
glow_intensity = p_intensity;
-
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _update_glow();
}
-float Environment::get_glow_intensity() const {
+float Environment::get_glow_intensity() const {
return glow_intensity;
}
void Environment::set_glow_strength(float p_strength) {
-
glow_strength = p_strength;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _update_glow();
}
-float Environment::get_glow_strength() const {
+float Environment::get_glow_strength() const {
return glow_strength;
}
-void Environment::set_glow_bloom(float p_threshold) {
+void Environment::set_glow_mix(float p_mix) {
+ glow_mix = p_mix;
+ _update_glow();
+}
- glow_bloom = p_threshold;
+float Environment::get_glow_mix() const {
+ return glow_mix;
+}
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+void Environment::set_glow_bloom(float p_threshold) {
+ glow_bloom = p_threshold;
+ _update_glow();
}
-float Environment::get_glow_bloom() const {
+float Environment::get_glow_bloom() const {
return glow_bloom;
}
void Environment::set_glow_blend_mode(GlowBlendMode p_mode) {
-
glow_blend_mode = p_mode;
-
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _update_glow();
+ _change_notify();
}
-Environment::GlowBlendMode Environment::get_glow_blend_mode() const {
+Environment::GlowBlendMode Environment::get_glow_blend_mode() const {
return glow_blend_mode;
}
void Environment::set_glow_hdr_bleed_threshold(float p_threshold) {
-
glow_hdr_bleed_threshold = p_threshold;
-
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _update_glow();
}
-float Environment::get_glow_hdr_bleed_threshold() const {
+float Environment::get_glow_hdr_bleed_threshold() const {
return glow_hdr_bleed_threshold;
}
-void Environment::set_glow_hdr_luminance_cap(float p_amount) {
-
- glow_hdr_luminance_cap = p_amount;
-
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
-}
-float Environment::get_glow_hdr_luminance_cap() const {
-
- return glow_hdr_luminance_cap;
-}
-
void Environment::set_glow_hdr_bleed_scale(float p_scale) {
-
glow_hdr_bleed_scale = p_scale;
-
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _update_glow();
}
-float Environment::get_glow_hdr_bleed_scale() const {
+float Environment::get_glow_hdr_bleed_scale() const {
return glow_hdr_bleed_scale;
}
-void Environment::set_glow_bicubic_upscale(bool p_enable) {
-
- glow_bicubic_upscale = p_enable;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+void Environment::set_glow_hdr_luminance_cap(float p_amount) {
+ glow_hdr_luminance_cap = p_amount;
+ _update_glow();
}
-bool Environment::is_glow_bicubic_upscale_enabled() const {
+float Environment::get_glow_hdr_luminance_cap() const {
+ return glow_hdr_luminance_cap;
+}
- return glow_bicubic_upscale;
+void Environment::_update_glow() {
+ RS::get_singleton()->environment_set_glow(
+ environment,
+ glow_enabled,
+ glow_levels,
+ glow_intensity,
+ glow_strength,
+ glow_mix,
+ glow_bloom,
+ RS::EnvironmentGlowBlendMode(glow_blend_mode),
+ glow_hdr_bleed_threshold,
+ glow_hdr_bleed_scale,
+ glow_hdr_luminance_cap);
}
-void Environment::set_dof_blur_far_enabled(bool p_enable) {
+// Fog
- dof_blur_far_enabled = p_enable;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+void Environment::set_fog_enabled(bool p_enabled) {
+ fog_enabled = p_enabled;
+ _update_fog();
_change_notify();
}
-bool Environment::is_dof_blur_far_enabled() const {
-
- return dof_blur_far_enabled;
+bool Environment::is_fog_enabled() const {
+ return fog_enabled;
}
-void Environment::set_dof_blur_far_distance(float p_distance) {
-
- dof_blur_far_distance = p_distance;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+void Environment::set_fog_light_color(const Color &p_light_color) {
+ fog_light_color = p_light_color;
+ _update_fog();
}
-float Environment::get_dof_blur_far_distance() const {
-
- return dof_blur_far_distance;
+Color Environment::get_fog_light_color() const {
+ return fog_light_color;
}
-
-void Environment::set_dof_blur_far_transition(float p_distance) {
-
- dof_blur_far_transition = p_distance;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+void Environment::set_fog_light_energy(float p_amount) {
+ fog_light_energy = p_amount;
+ _update_fog();
}
-float Environment::get_dof_blur_far_transition() const {
-
- return dof_blur_far_transition;
+float Environment::get_fog_light_energy() const {
+ return fog_light_energy;
}
-
-void Environment::set_dof_blur_far_amount(float p_amount) {
-
- dof_blur_far_amount = p_amount;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+void Environment::set_fog_sun_scatter(float p_amount) {
+ fog_sun_scatter = p_amount;
+ _update_fog();
}
-float Environment::get_dof_blur_far_amount() const {
-
- return dof_blur_far_amount;
+float Environment::get_fog_sun_scatter() const {
+ return fog_sun_scatter;
+}
+void Environment::set_fog_density(float p_amount) {
+ fog_density = p_amount;
+ _update_fog();
+}
+float Environment::get_fog_density() const {
+ return fog_density;
+}
+void Environment::set_fog_height(float p_amount) {
+ fog_height = p_amount;
+ _update_fog();
+}
+float Environment::get_fog_height() const {
+ return fog_height;
+}
+void Environment::set_fog_height_density(float p_amount) {
+ fog_height_density = p_amount;
+ _update_fog();
+}
+float Environment::get_fog_height_density() const {
+ return fog_height_density;
}
-void Environment::set_dof_blur_far_quality(DOFBlurQuality p_quality) {
-
- dof_blur_far_quality = p_quality;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+void Environment::_update_fog() {
+ RS::get_singleton()->environment_set_fog(
+ environment,
+ fog_enabled,
+ fog_light_color,
+ fog_light_energy,
+ fog_sun_scatter,
+ fog_density,
+ fog_height,
+ fog_height_density);
}
-Environment::DOFBlurQuality Environment::get_dof_blur_far_quality() const {
+// Volumetric Fog
- return dof_blur_far_quality;
+void Environment::_update_volumetric_fog() {
+ RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter));
}
-void Environment::set_dof_blur_near_enabled(bool p_enable) {
-
- dof_blur_near_enabled = p_enable;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+void Environment::set_volumetric_fog_enabled(bool p_enable) {
+ volumetric_fog_enabled = p_enable;
+ _update_volumetric_fog();
_change_notify();
}
-bool Environment::is_dof_blur_near_enabled() const {
-
- return dof_blur_near_enabled;
+bool Environment::is_volumetric_fog_enabled() const {
+ return volumetric_fog_enabled;
}
-
-void Environment::set_dof_blur_near_distance(float p_distance) {
-
- dof_blur_near_distance = p_distance;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+void Environment::set_volumetric_fog_density(float p_density) {
+ p_density = CLAMP(p_density, 0.0000001, 1.0);
+ volumetric_fog_density = p_density;
+ _update_volumetric_fog();
}
-
-float Environment::get_dof_blur_near_distance() const {
-
- return dof_blur_near_distance;
+float Environment::get_volumetric_fog_density() const {
+ return volumetric_fog_density;
}
-
-void Environment::set_dof_blur_near_transition(float p_distance) {
-
- dof_blur_near_transition = p_distance;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+void Environment::set_volumetric_fog_light(Color p_color) {
+ volumetric_fog_light = p_color;
+ _update_volumetric_fog();
}
-
-float Environment::get_dof_blur_near_transition() const {
-
- return dof_blur_near_transition;
+Color Environment::get_volumetric_fog_light() const {
+ return volumetric_fog_light;
}
-
-void Environment::set_dof_blur_near_amount(float p_amount) {
-
- dof_blur_near_amount = p_amount;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+void Environment::set_volumetric_fog_light_energy(float p_begin) {
+ volumetric_fog_light_energy = p_begin;
+ _update_volumetric_fog();
}
-
-float Environment::get_dof_blur_near_amount() const {
-
- return dof_blur_near_amount;
+float Environment::get_volumetric_fog_light_energy() const {
+ return volumetric_fog_light_energy;
}
-
-void Environment::set_dof_blur_near_quality(DOFBlurQuality p_quality) {
-
- dof_blur_near_quality = p_quality;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+void Environment::set_volumetric_fog_length(float p_length) {
+ volumetric_fog_length = p_length;
+ _update_volumetric_fog();
}
-
-Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const {
-
- return dof_blur_near_quality;
+float Environment::get_volumetric_fog_length() const {
+ return volumetric_fog_length;
}
-
-void Environment::set_fog_enabled(bool p_enabled) {
-
- fog_enabled = p_enabled;
- VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
- _change_notify();
+void Environment::set_volumetric_fog_detail_spread(float p_detail_spread) {
+ volumetric_fog_detail_spread = p_detail_spread;
+ _update_volumetric_fog();
}
-
-bool Environment::is_fog_enabled() const {
-
- return fog_enabled;
+float Environment::get_volumetric_fog_detail_spread() const {
+ return volumetric_fog_detail_spread;
}
-void Environment::set_fog_color(const Color &p_color) {
-
- fog_color = p_color;
- VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
+void Environment::set_volumetric_fog_gi_inject(float p_gi_inject) {
+ volumetric_fog_gi_inject = p_gi_inject;
+ _update_volumetric_fog();
}
-Color Environment::get_fog_color() const {
-
- return fog_color;
+float Environment::get_volumetric_fog_gi_inject() const {
+ return volumetric_fog_gi_inject;
}
-void Environment::set_fog_sun_color(const Color &p_color) {
-
- fog_sun_color = p_color;
- VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
+void Environment::set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter) {
+ volumetric_fog_shadow_filter = p_filter;
+ _update_volumetric_fog();
}
-Color Environment::get_fog_sun_color() const {
- return fog_sun_color;
+Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_filter() const {
+ return volumetric_fog_shadow_filter;
}
-void Environment::set_fog_sun_amount(float p_amount) {
+// Adjustment
- fog_sun_amount = p_amount;
- VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
+void Environment::set_adjustment_enabled(bool p_enabled) {
+ adjustment_enabled = p_enabled;
+ _update_adjustment();
+ _change_notify();
}
-float Environment::get_fog_sun_amount() const {
- return fog_sun_amount;
+bool Environment::is_adjustment_enabled() const {
+ return adjustment_enabled;
}
-void Environment::set_fog_depth_enabled(bool p_enabled) {
-
- fog_depth_enabled = p_enabled;
- VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+void Environment::set_adjustment_brightness(float p_brightness) {
+ adjustment_brightness = p_brightness;
+ _update_adjustment();
}
-bool Environment::is_fog_depth_enabled() const {
- return fog_depth_enabled;
+float Environment::get_adjustment_brightness() const {
+ return adjustment_brightness;
}
-void Environment::set_fog_depth_begin(float p_distance) {
-
- fog_depth_begin = p_distance;
- VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+void Environment::set_adjustment_contrast(float p_contrast) {
+ adjustment_contrast = p_contrast;
+ _update_adjustment();
}
-float Environment::get_fog_depth_begin() const {
- return fog_depth_begin;
+float Environment::get_adjustment_contrast() const {
+ return adjustment_contrast;
}
-void Environment::set_fog_depth_end(float p_distance) {
-
- fog_depth_end = p_distance;
- VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+void Environment::set_adjustment_saturation(float p_saturation) {
+ adjustment_saturation = p_saturation;
+ _update_adjustment();
}
-float Environment::get_fog_depth_end() const {
-
- return fog_depth_end;
+float Environment::get_adjustment_saturation() const {
+ return adjustment_saturation;
}
-void Environment::set_fog_depth_curve(float p_curve) {
+void Environment::set_adjustment_color_correction(const Ref<Texture2D> &p_ramp) {
+ adjustment_color_correction = p_ramp;
+ _update_adjustment();
+}
- fog_depth_curve = p_curve;
- VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+Ref<Texture2D> Environment::get_adjustment_color_correction() const {
+ return adjustment_color_correction;
}
-float Environment::get_fog_depth_curve() const {
- return fog_depth_curve;
+void Environment::_update_adjustment() {
+ RS::get_singleton()->environment_set_adjustment(
+ environment,
+ adjustment_enabled,
+ adjustment_brightness,
+ adjustment_contrast,
+ adjustment_saturation,
+ adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
}
-void Environment::set_fog_transmit_enabled(bool p_enabled) {
+// Private methods, constructor and destructor
- fog_transmit_enabled = p_enabled;
- VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
-}
-bool Environment::is_fog_transmit_enabled() const {
+void Environment::_validate_property(PropertyInfo &property) const {
+ if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") {
+ if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ }
+ }
- return fog_transmit_enabled;
-}
+ if (property.name == "glow_intensity" && glow_blend_mode == GLOW_BLEND_MODE_MIX) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ }
-void Environment::set_fog_transmit_curve(float p_curve) {
+ if (property.name == "glow_mix" && glow_blend_mode != GLOW_BLEND_MODE_MIX) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ }
- fog_transmit_curve = p_curve;
- VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
-}
-float Environment::get_fog_transmit_curve() const {
+ if (property.name == "background_color") {
+ if (bg_mode != BG_COLOR && ambient_source != AMBIENT_SOURCE_COLOR) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ }
+ }
- return fog_transmit_curve;
-}
+ if (property.name == "background_canvas_max_layer") {
+ if (bg_mode != BG_CANVAS) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ }
+ }
-void Environment::set_fog_height_enabled(bool p_enabled) {
+ if (property.name == "background_camera_feed_id") {
+ if (bg_mode != BG_CAMERA_FEED) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+ }
- fog_height_enabled = p_enabled;
- VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
-}
-bool Environment::is_fog_height_enabled() const {
+ static const char *hide_prefixes[] = {
+ "fog_",
+ "volumetric_fog_",
+ "auto_exposure_",
+ "ss_reflections_",
+ "ssao_",
+ "glow_",
+ "adjustment_",
+ nullptr
- return fog_height_enabled;
-}
+ };
-void Environment::set_fog_height_min(float p_distance) {
+ static const char *high_end_prefixes[] = {
+ "auto_exposure_",
+ "tonemap_",
+ "ss_reflections_",
+ "ssao_",
+ nullptr
- fog_height_min = p_distance;
- VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
-}
-float Environment::get_fog_height_min() const {
+ };
- return fog_height_min;
-}
+ const char **prefixes = hide_prefixes;
+ while (*prefixes) {
+ String prefix = String(*prefixes);
-void Environment::set_fog_height_max(float p_distance) {
+ String enabled = prefix + "enabled";
+ if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ return;
+ }
- fog_height_max = p_distance;
- VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
-}
-float Environment::get_fog_height_max() const {
+ prefixes++;
+ }
- return fog_height_max;
-}
+ if (RenderingServer::get_singleton()->is_low_end()) {
+ prefixes = high_end_prefixes;
+ while (*prefixes) {
+ String prefix = String(*prefixes);
-void Environment::set_fog_height_curve(float p_distance) {
+ if (property.name.begins_with(prefix)) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ return;
+ }
- fog_height_curve = p_distance;
- VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
+ prefixes++;
+ }
+ }
}
-float Environment::get_fog_height_curve() const {
- return fog_height_curve;
+#ifndef DISABLE_DEPRECATED
+// Kept for compatibility from 3.x to 4.0.
+bool Environment::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "background_sky") {
+ set_sky(p_value);
+ return true;
+ } else if (p_name == "background_sky_custom_fov") {
+ set_sky_custom_fov(p_value);
+ return true;
+ } else if (p_name == "background_sky_orientation") {
+ Vector3 euler = p_value.operator Basis().get_euler();
+ set_sky_rotation(euler);
+ return true;
+ } else {
+ return false;
+ }
}
+#endif
void Environment::_bind_methods() {
+ // Background
ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background);
- ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky);
- ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov);
- ClassDB::bind_method(D_METHOD("set_sky_orientation", "orientation"), &Environment::set_sky_orientation);
- ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation);
- ClassDB::bind_method(D_METHOD("set_sky_rotation_degrees", "euler_degrees"), &Environment::set_sky_rotation_degrees);
- ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color);
- ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy);
- ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer);
- ClassDB::bind_method(D_METHOD("set_ambient_light_color", "color"), &Environment::set_ambient_light_color);
- ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy);
- ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "energy"), &Environment::set_ambient_light_sky_contribution);
- ClassDB::bind_method(D_METHOD("set_camera_feed_id", "camera_feed_id"), &Environment::set_camera_feed_id);
-
ClassDB::bind_method(D_METHOD("get_background"), &Environment::get_background);
+ ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky);
ClassDB::bind_method(D_METHOD("get_sky"), &Environment::get_sky);
+ ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov);
ClassDB::bind_method(D_METHOD("get_sky_custom_fov"), &Environment::get_sky_custom_fov);
- ClassDB::bind_method(D_METHOD("get_sky_orientation"), &Environment::get_sky_orientation);
+ ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation);
ClassDB::bind_method(D_METHOD("get_sky_rotation"), &Environment::get_sky_rotation);
- ClassDB::bind_method(D_METHOD("get_sky_rotation_degrees"), &Environment::get_sky_rotation_degrees);
+ ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color);
+ ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy);
ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy);
+ ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer);
ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer);
- ClassDB::bind_method(D_METHOD("get_ambient_light_color"), &Environment::get_ambient_light_color);
- ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy);
- ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution);
+ ClassDB::bind_method(D_METHOD("set_camera_feed_id", "id"), &Environment::set_camera_feed_id);
ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &Environment::get_camera_feed_id);
ADD_GROUP("Background", "background_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Color+Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov");
- ADD_PROPERTY(PropertyInfo(Variant::BASIS, "background_sky_orientation"), "set_sky_orientation", "get_sky_orientation");
- // Only display rotation in degrees in the inspector (like in Spatial).
- // This avoids displaying the same information twice.
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation", PROPERTY_HINT_NONE, "", 0), "set_sky_rotation", "get_sky_rotation");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_sky_rotation_degrees", "get_sky_rotation_degrees");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_camera_feed_id", PROPERTY_HINT_RANGE, "1,10,1"), "set_camera_feed_id", "get_camera_feed_id");
- ADD_GROUP("Ambient Light", "ambient_light_");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution");
-
- ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled);
- ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled);
-
- ClassDB::bind_method(D_METHOD("set_fog_color", "color"), &Environment::set_fog_color);
- ClassDB::bind_method(D_METHOD("get_fog_color"), &Environment::get_fog_color);
-
- ClassDB::bind_method(D_METHOD("set_fog_sun_color", "color"), &Environment::set_fog_sun_color);
- ClassDB::bind_method(D_METHOD("get_fog_sun_color"), &Environment::get_fog_sun_color);
-
- ClassDB::bind_method(D_METHOD("set_fog_sun_amount", "amount"), &Environment::set_fog_sun_amount);
- ClassDB::bind_method(D_METHOD("get_fog_sun_amount"), &Environment::get_fog_sun_amount);
-
- ClassDB::bind_method(D_METHOD("set_fog_depth_enabled", "enabled"), &Environment::set_fog_depth_enabled);
- ClassDB::bind_method(D_METHOD("is_fog_depth_enabled"), &Environment::is_fog_depth_enabled);
- ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin);
- ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin);
+ ADD_GROUP("Sky", "sky_");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation"), "set_sky_rotation", "get_sky_rotation");
- ClassDB::bind_method(D_METHOD("set_fog_depth_end", "distance"), &Environment::set_fog_depth_end);
- ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end);
+ // Ambient light
- ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve);
- ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve);
-
- ClassDB::bind_method(D_METHOD("set_fog_transmit_enabled", "enabled"), &Environment::set_fog_transmit_enabled);
- ClassDB::bind_method(D_METHOD("is_fog_transmit_enabled"), &Environment::is_fog_transmit_enabled);
-
- ClassDB::bind_method(D_METHOD("set_fog_transmit_curve", "curve"), &Environment::set_fog_transmit_curve);
- ClassDB::bind_method(D_METHOD("get_fog_transmit_curve"), &Environment::get_fog_transmit_curve);
-
- ClassDB::bind_method(D_METHOD("set_fog_height_enabled", "enabled"), &Environment::set_fog_height_enabled);
- ClassDB::bind_method(D_METHOD("is_fog_height_enabled"), &Environment::is_fog_height_enabled);
-
- ClassDB::bind_method(D_METHOD("set_fog_height_min", "height"), &Environment::set_fog_height_min);
- ClassDB::bind_method(D_METHOD("get_fog_height_min"), &Environment::get_fog_height_min);
+ ClassDB::bind_method(D_METHOD("set_ambient_light_color", "color"), &Environment::set_ambient_light_color);
+ ClassDB::bind_method(D_METHOD("get_ambient_light_color"), &Environment::get_ambient_light_color);
+ ClassDB::bind_method(D_METHOD("set_ambient_source", "source"), &Environment::set_ambient_source);
+ ClassDB::bind_method(D_METHOD("get_ambient_source"), &Environment::get_ambient_source);
+ ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy);
+ ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy);
+ ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "ratio"), &Environment::set_ambient_light_sky_contribution);
+ ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution);
+ ClassDB::bind_method(D_METHOD("set_reflection_source", "source"), &Environment::set_reflection_source);
+ ClassDB::bind_method(D_METHOD("get_reflection_source"), &Environment::get_reflection_source);
+ ClassDB::bind_method(D_METHOD("set_ao_color", "color"), &Environment::set_ao_color);
+ ClassDB::bind_method(D_METHOD("get_ao_color"), &Environment::get_ao_color);
- ClassDB::bind_method(D_METHOD("set_fog_height_max", "height"), &Environment::set_fog_height_max);
- ClassDB::bind_method(D_METHOD("get_fog_height_max"), &Environment::get_fog_height_max);
+ ADD_GROUP("Ambient Light", "ambient_light_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Color,Sky"), "set_ambient_source", "get_ambient_source");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_occlusion_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ao_color", "get_ao_color");
- ClassDB::bind_method(D_METHOD("set_fog_height_curve", "curve"), &Environment::set_fog_height_curve);
- ClassDB::bind_method(D_METHOD("get_fog_height_curve"), &Environment::get_fog_height_curve);
+ ADD_GROUP("Reflected Light", "reflected_light_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "reflected_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Sky"), "set_reflection_source", "get_reflection_source");
- ADD_GROUP("Fog", "fog_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve");
+ // Tonemap
ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper);
ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper);
-
ClassDB::bind_method(D_METHOD("set_tonemap_exposure", "exposure"), &Environment::set_tonemap_exposure);
ClassDB::bind_method(D_METHOD("get_tonemap_exposure"), &Environment::get_tonemap_exposure);
-
ClassDB::bind_method(D_METHOD("set_tonemap_white", "white"), &Environment::set_tonemap_white);
ClassDB::bind_method(D_METHOD("get_tonemap_white"), &Environment::get_tonemap_white);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure", "auto_exposure"), &Environment::set_tonemap_auto_exposure);
- ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure"), &Environment::get_tonemap_auto_exposure);
-
+ ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_enabled", "enabled"), &Environment::set_tonemap_auto_exposure_enabled);
+ ClassDB::bind_method(D_METHOD("is_tonemap_auto_exposure_enabled"), &Environment::is_tonemap_auto_exposure_enabled);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_max", "exposure_max"), &Environment::set_tonemap_auto_exposure_max);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_max"), &Environment::get_tonemap_auto_exposure_max);
-
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_min", "exposure_min"), &Environment::set_tonemap_auto_exposure_min);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_min"), &Environment::get_tonemap_auto_exposure_min);
-
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_speed", "exposure_speed"), &Environment::set_tonemap_auto_exposure_speed);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_speed"), &Environment::get_tonemap_auto_exposure_speed);
-
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_grey", "exposure_grey"), &Environment::set_tonemap_auto_exposure_grey);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey);
ADD_GROUP("Tonemap", "tonemap_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,ACES"), "set_tonemapper", "get_tonemapper");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
ADD_GROUP("Auto Exposure", "auto_exposure_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_exposure_enabled"), "set_tonemap_auto_exposure", "get_tonemap_auto_exposure");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_exposure_enabled"), "set_tonemap_auto_exposure_enabled", "is_tonemap_auto_exposure_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed");
+
+ // SSR
ClassDB::bind_method(D_METHOD("set_ssr_enabled", "enabled"), &Environment::set_ssr_enabled);
ClassDB::bind_method(D_METHOD("is_ssr_enabled"), &Environment::is_ssr_enabled);
-
ClassDB::bind_method(D_METHOD("set_ssr_max_steps", "max_steps"), &Environment::set_ssr_max_steps);
ClassDB::bind_method(D_METHOD("get_ssr_max_steps"), &Environment::get_ssr_max_steps);
-
ClassDB::bind_method(D_METHOD("set_ssr_fade_in", "fade_in"), &Environment::set_ssr_fade_in);
ClassDB::bind_method(D_METHOD("get_ssr_fade_in"), &Environment::get_ssr_fade_in);
-
ClassDB::bind_method(D_METHOD("set_ssr_fade_out", "fade_out"), &Environment::set_ssr_fade_out);
ClassDB::bind_method(D_METHOD("get_ssr_fade_out"), &Environment::get_ssr_fade_out);
-
ClassDB::bind_method(D_METHOD("set_ssr_depth_tolerance", "depth_tolerance"), &Environment::set_ssr_depth_tolerance);
ClassDB::bind_method(D_METHOD("get_ssr_depth_tolerance"), &Environment::get_ssr_depth_tolerance);
- ClassDB::bind_method(D_METHOD("set_ssr_rough", "rough"), &Environment::set_ssr_rough);
- ClassDB::bind_method(D_METHOD("is_ssr_rough"), &Environment::is_ssr_rough);
-
ADD_GROUP("SS Reflections", "ss_reflections_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_enabled"), "set_ssr_enabled", "is_ssr_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ss_reflections_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_roughness"), "set_ssr_rough", "is_ssr_rough");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.01,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance");
+
+ // SSAO
ClassDB::bind_method(D_METHOD("set_ssao_enabled", "enabled"), &Environment::set_ssao_enabled);
ClassDB::bind_method(D_METHOD("is_ssao_enabled"), &Environment::is_ssao_enabled);
-
ClassDB::bind_method(D_METHOD("set_ssao_radius", "radius"), &Environment::set_ssao_radius);
ClassDB::bind_method(D_METHOD("get_ssao_radius"), &Environment::get_ssao_radius);
-
ClassDB::bind_method(D_METHOD("set_ssao_intensity", "intensity"), &Environment::set_ssao_intensity);
ClassDB::bind_method(D_METHOD("get_ssao_intensity"), &Environment::get_ssao_intensity);
-
- ClassDB::bind_method(D_METHOD("set_ssao_radius2", "radius"), &Environment::set_ssao_radius2);
- ClassDB::bind_method(D_METHOD("get_ssao_radius2"), &Environment::get_ssao_radius2);
-
- ClassDB::bind_method(D_METHOD("set_ssao_intensity2", "intensity"), &Environment::set_ssao_intensity2);
- ClassDB::bind_method(D_METHOD("get_ssao_intensity2"), &Environment::get_ssao_intensity2);
-
ClassDB::bind_method(D_METHOD("set_ssao_bias", "bias"), &Environment::set_ssao_bias);
ClassDB::bind_method(D_METHOD("get_ssao_bias"), &Environment::get_ssao_bias);
-
ClassDB::bind_method(D_METHOD("set_ssao_direct_light_affect", "amount"), &Environment::set_ssao_direct_light_affect);
ClassDB::bind_method(D_METHOD("get_ssao_direct_light_affect"), &Environment::get_ssao_direct_light_affect);
-
ClassDB::bind_method(D_METHOD("set_ssao_ao_channel_affect", "amount"), &Environment::set_ssao_ao_channel_affect);
ClassDB::bind_method(D_METHOD("get_ssao_ao_channel_affect"), &Environment::get_ssao_ao_channel_affect);
-
- ClassDB::bind_method(D_METHOD("set_ssao_color", "color"), &Environment::set_ssao_color);
- ClassDB::bind_method(D_METHOD("get_ssao_color"), &Environment::get_ssao_color);
-
ClassDB::bind_method(D_METHOD("set_ssao_blur", "mode"), &Environment::set_ssao_blur);
ClassDB::bind_method(D_METHOD("get_ssao_blur"), &Environment::get_ssao_blur);
-
- ClassDB::bind_method(D_METHOD("set_ssao_quality", "quality"), &Environment::set_ssao_quality);
- ClassDB::bind_method(D_METHOD("get_ssao_quality"), &Environment::get_ssao_quality);
-
ClassDB::bind_method(D_METHOD("set_ssao_edge_sharpness", "edge_sharpness"), &Environment::set_ssao_edge_sharpness);
ClassDB::bind_method(D_METHOD("get_ssao_edge_sharpness"), &Environment::get_ssao_edge_sharpness);
ADD_GROUP("SSAO", "ssao_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_radius2", "get_ssao_radius2");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity2", "get_ssao_intensity2");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ssao_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ssao_color", "get_ssao_color");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_ssao_quality", "get_ssao_quality");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.01"), "set_ssao_radius", "get_ssao_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.01"), "set_ssao_intensity", "get_ssao_intensity");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_blur", PROPERTY_HINT_ENUM, "Disabled,1x1,2x2,3x3"), "set_ssao_blur", "get_ssao_blur");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness");
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &Environment::set_dof_blur_far_enabled);
- ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &Environment::is_dof_blur_far_enabled);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &Environment::set_dof_blur_far_distance);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &Environment::get_dof_blur_far_distance);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &Environment::set_dof_blur_far_transition);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &Environment::get_dof_blur_far_transition);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_amount", "intensity"), &Environment::set_dof_blur_far_amount);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_amount"), &Environment::get_dof_blur_far_amount);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_quality", "intensity"), &Environment::set_dof_blur_far_quality);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_quality"), &Environment::get_dof_blur_far_quality);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &Environment::set_dof_blur_near_enabled);
- ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &Environment::is_dof_blur_near_enabled);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &Environment::set_dof_blur_near_distance);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &Environment::get_dof_blur_near_distance);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &Environment::set_dof_blur_near_transition);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &Environment::get_dof_blur_near_transition);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_amount", "intensity"), &Environment::set_dof_blur_near_amount);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_amount"), &Environment::get_dof_blur_near_amount);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_quality", "level"), &Environment::set_dof_blur_near_quality);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_quality"), &Environment::get_dof_blur_near_quality);
-
- ADD_GROUP("DOF Far Blur", "dof_blur_far_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_far_amount", "get_dof_blur_far_amount");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_far_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_far_quality", "get_dof_blur_far_quality");
-
- ADD_GROUP("DOF Near Blur", "dof_blur_near_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_near_amount", "get_dof_blur_near_amount");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_near_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_near_quality", "get_dof_blur_near_quality");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness");
+
+ // SDFGI
+
+ ClassDB::bind_method(D_METHOD("set_sdfgi_enabled", "enabled"), &Environment::set_sdfgi_enabled);
+ ClassDB::bind_method(D_METHOD("is_sdfgi_enabled"), &Environment::is_sdfgi_enabled);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_cascades", "amount"), &Environment::set_sdfgi_cascades);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_cascades"), &Environment::get_sdfgi_cascades);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_min_cell_size", "size"), &Environment::set_sdfgi_min_cell_size);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_min_cell_size"), &Environment::get_sdfgi_min_cell_size);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_max_distance", "distance"), &Environment::set_sdfgi_max_distance);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_max_distance"), &Environment::get_sdfgi_max_distance);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_cascade0_distance", "distance"), &Environment::set_sdfgi_cascade0_distance);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_cascade0_distance"), &Environment::get_sdfgi_cascade0_distance);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_y_scale", "scale"), &Environment::set_sdfgi_y_scale);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_y_scale"), &Environment::get_sdfgi_y_scale);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_use_occlusion", "enable"), &Environment::set_sdfgi_use_occlusion);
+ ClassDB::bind_method(D_METHOD("is_sdfgi_using_occlusion"), &Environment::is_sdfgi_using_occlusion);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_use_multi_bounce", "enable"), &Environment::set_sdfgi_use_multi_bounce);
+ ClassDB::bind_method(D_METHOD("is_sdfgi_using_multi_bounce"), &Environment::is_sdfgi_using_multi_bounce);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_read_sky_light", "enable"), &Environment::set_sdfgi_read_sky_light);
+ ClassDB::bind_method(D_METHOD("is_sdfgi_reading_sky_light"), &Environment::is_sdfgi_reading_sky_light);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_energy", "amount"), &Environment::set_sdfgi_energy);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_energy"), &Environment::get_sdfgi_energy);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_normal_bias", "bias"), &Environment::set_sdfgi_normal_bias);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_normal_bias"), &Environment::get_sdfgi_normal_bias);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_probe_bias", "bias"), &Environment::set_sdfgi_probe_bias);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_probe_bias"), &Environment::get_sdfgi_probe_bias);
+
+ ADD_GROUP("SDFGI", "sdfgi_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_enabled"), "set_sdfgi_enabled", "is_sdfgi_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_multi_bounce"), "set_sdfgi_use_multi_bounce", "is_sdfgi_using_multi_bounce");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_occlusion"), "set_sdfgi_use_occlusion", "is_sdfgi_using_occlusion");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_read_sky_light"), "set_sdfgi_read_sky_light", "is_sdfgi_reading_sky_light");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_ENUM, "4 Cascades,6 Cascades,8 Cascades"), "set_sdfgi_cascades", "get_sdfgi_cascades");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_max_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_max_distance", "get_sdfgi_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_y_scale", PROPERTY_HINT_ENUM, "Disable,75%,50%"), "set_sdfgi_y_scale", "get_sdfgi_y_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_energy"), "set_sdfgi_energy", "get_sdfgi_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_normal_bias"), "set_sdfgi_normal_bias", "get_sdfgi_normal_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_probe_bias"), "set_sdfgi_probe_bias", "get_sdfgi_probe_bias");
+
+ // Glow
ClassDB::bind_method(D_METHOD("set_glow_enabled", "enabled"), &Environment::set_glow_enabled);
ClassDB::bind_method(D_METHOD("is_glow_enabled"), &Environment::is_glow_enabled);
-
- ClassDB::bind_method(D_METHOD("set_glow_level", "idx", "enabled"), &Environment::set_glow_level);
+ ClassDB::bind_method(D_METHOD("set_glow_level_enabled", "idx", "enabled"), &Environment::set_glow_level_enabled);
ClassDB::bind_method(D_METHOD("is_glow_level_enabled", "idx"), &Environment::is_glow_level_enabled);
-
ClassDB::bind_method(D_METHOD("set_glow_intensity", "intensity"), &Environment::set_glow_intensity);
ClassDB::bind_method(D_METHOD("get_glow_intensity"), &Environment::get_glow_intensity);
-
ClassDB::bind_method(D_METHOD("set_glow_strength", "strength"), &Environment::set_glow_strength);
ClassDB::bind_method(D_METHOD("get_glow_strength"), &Environment::get_glow_strength);
-
+ ClassDB::bind_method(D_METHOD("set_glow_mix", "mix"), &Environment::set_glow_mix);
+ ClassDB::bind_method(D_METHOD("get_glow_mix"), &Environment::get_glow_mix);
ClassDB::bind_method(D_METHOD("set_glow_bloom", "amount"), &Environment::set_glow_bloom);
ClassDB::bind_method(D_METHOD("get_glow_bloom"), &Environment::get_glow_bloom);
-
ClassDB::bind_method(D_METHOD("set_glow_blend_mode", "mode"), &Environment::set_glow_blend_mode);
ClassDB::bind_method(D_METHOD("get_glow_blend_mode"), &Environment::get_glow_blend_mode);
-
ClassDB::bind_method(D_METHOD("set_glow_hdr_bleed_threshold", "threshold"), &Environment::set_glow_hdr_bleed_threshold);
ClassDB::bind_method(D_METHOD("get_glow_hdr_bleed_threshold"), &Environment::get_glow_hdr_bleed_threshold);
-
- ClassDB::bind_method(D_METHOD("set_glow_hdr_luminance_cap", "amount"), &Environment::set_glow_hdr_luminance_cap);
- ClassDB::bind_method(D_METHOD("get_glow_hdr_luminance_cap"), &Environment::get_glow_hdr_luminance_cap);
-
ClassDB::bind_method(D_METHOD("set_glow_hdr_bleed_scale", "scale"), &Environment::set_glow_hdr_bleed_scale);
ClassDB::bind_method(D_METHOD("get_glow_hdr_bleed_scale"), &Environment::get_glow_hdr_bleed_scale);
-
- ClassDB::bind_method(D_METHOD("set_glow_bicubic_upscale", "enabled"), &Environment::set_glow_bicubic_upscale);
- ClassDB::bind_method(D_METHOD("is_glow_bicubic_upscale_enabled"), &Environment::is_glow_bicubic_upscale_enabled);
+ ClassDB::bind_method(D_METHOD("set_glow_hdr_luminance_cap", "amount"), &Environment::set_glow_hdr_luminance_cap);
+ ClassDB::bind_method(D_METHOD("get_glow_hdr_luminance_cap"), &Environment::get_glow_hdr_luminance_cap);
ADD_GROUP("Glow", "glow_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_enabled"), "set_glow_enabled", "is_glow_enabled");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/1"), "set_glow_level", "is_glow_level_enabled", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/2"), "set_glow_level", "is_glow_level_enabled", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/3"), "set_glow_level", "is_glow_level_enabled", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/4"), "set_glow_level", "is_glow_level_enabled", 3);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/5"), "set_glow_level", "is_glow_level_enabled", 4);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/6"), "set_glow_level", "is_glow_level_enabled", 5);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level", "is_glow_level_enabled", 6);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_bloom", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_bloom", "get_glow_bloom");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace"), "set_glow_blend_mode", "get_glow_blend_mode");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_bicubic_upscale"), "set_glow_bicubic_upscale", "is_glow_bicubic_upscale_enabled");
-
- ClassDB::bind_method(D_METHOD("set_adjustment_enable", "enabled"), &Environment::set_adjustment_enable);
- ClassDB::bind_method(D_METHOD("is_adjustment_enabled"), &Environment::is_adjustment_enabled);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/1"), "set_glow_level_enabled", "is_glow_level_enabled", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/2"), "set_glow_level_enabled", "is_glow_level_enabled", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/3"), "set_glow_level_enabled", "is_glow_level_enabled", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/4"), "set_glow_level_enabled", "is_glow_level_enabled", 3);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/5"), "set_glow_level_enabled", "is_glow_level_enabled", 4);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/6"), "set_glow_level_enabled", "is_glow_level_enabled", 5);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level_enabled", "is_glow_level_enabled", 6);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_mix", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_glow_mix", "get_glow_mix");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_bloom", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_bloom", "get_glow_bloom");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace,Mix"), "set_glow_blend_mode", "get_glow_blend_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap");
+
+ // Fog
+
+ ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled);
+ ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled);
+ ClassDB::bind_method(D_METHOD("set_fog_light_color", "light_color"), &Environment::set_fog_light_color);
+ ClassDB::bind_method(D_METHOD("get_fog_light_color"), &Environment::get_fog_light_color);
+ ClassDB::bind_method(D_METHOD("set_fog_light_energy", "light_energy"), &Environment::set_fog_light_energy);
+ ClassDB::bind_method(D_METHOD("get_fog_light_energy"), &Environment::get_fog_light_energy);
+ ClassDB::bind_method(D_METHOD("set_fog_sun_scatter", "sun_scatter"), &Environment::set_fog_sun_scatter);
+ ClassDB::bind_method(D_METHOD("get_fog_sun_scatter"), &Environment::get_fog_sun_scatter);
+ ClassDB::bind_method(D_METHOD("set_fog_density", "density"), &Environment::set_fog_density);
+ ClassDB::bind_method(D_METHOD("get_fog_density"), &Environment::get_fog_density);
+
+ ClassDB::bind_method(D_METHOD("set_fog_height", "height"), &Environment::set_fog_height);
+ ClassDB::bind_method(D_METHOD("get_fog_height"), &Environment::get_fog_height);
+
+ ClassDB::bind_method(D_METHOD("set_fog_height_density", "height_density"), &Environment::set_fog_height_density);
+ ClassDB::bind_method(D_METHOD("get_fog_height_density"), &Environment::get_fog_height_density);
+
+ ADD_GROUP("Fog", "fog_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_fog_light_color", "get_fog_light_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_fog_light_energy", "get_fog_light_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_scatter", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_fog_sun_scatter", "get_fog_sun_scatter");
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,16,0.0001"), "set_fog_density", "get_fog_density");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater"), "set_fog_height", "get_fog_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "0,128,0.001,or_greater"), "set_fog_height_density", "get_fog_height_density");
+
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_enabled", "enabled"), &Environment::set_volumetric_fog_enabled);
+ ClassDB::bind_method(D_METHOD("is_volumetric_fog_enabled"), &Environment::is_volumetric_fog_enabled);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_light", "color"), &Environment::set_volumetric_fog_light);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_light"), &Environment::get_volumetric_fog_light);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_density", "density"), &Environment::set_volumetric_fog_density);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_density"), &Environment::get_volumetric_fog_density);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_light_energy", "begin"), &Environment::set_volumetric_fog_light_energy);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_light_energy"), &Environment::get_volumetric_fog_light_energy);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_length", "length"), &Environment::set_volumetric_fog_length);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_length"), &Environment::get_volumetric_fog_length);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_detail_spread", "detail_spread"), &Environment::set_volumetric_fog_detail_spread);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_detail_spread"), &Environment::get_volumetric_fog_detail_spread);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_gi_inject", "gi_inject"), &Environment::set_volumetric_fog_gi_inject);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_shadow_filter", "shadow_filter"), &Environment::set_volumetric_fog_shadow_filter);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_shadow_filter"), &Environment::get_volumetric_fog_shadow_filter);
+
+ ADD_GROUP("Volumetric Fog", "volumetric_fog_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_enabled"), "set_volumetric_fog_enabled", "is_volumetric_fog_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_volumetric_fog_density", "get_volumetric_fog_density");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "volumetric_fog_light", PROPERTY_HINT_COLOR_NO_ALPHA), "set_volumetric_fog_light", "get_volumetric_fog_light");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_light_energy", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_light_energy", "get_volumetric_fog_light_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "volumetric_fog_shadow_filter", PROPERTY_HINT_ENUM, "Disabled,Low,Medium,High"), "set_volumetric_fog_shadow_filter", "get_volumetric_fog_shadow_filter");
+
+ // Adjustment
+
+ ClassDB::bind_method(D_METHOD("set_adjustment_enabled", "enabled"), &Environment::set_adjustment_enabled);
+ ClassDB::bind_method(D_METHOD("is_adjustment_enabled"), &Environment::is_adjustment_enabled);
ClassDB::bind_method(D_METHOD("set_adjustment_brightness", "brightness"), &Environment::set_adjustment_brightness);
ClassDB::bind_method(D_METHOD("get_adjustment_brightness"), &Environment::get_adjustment_brightness);
-
ClassDB::bind_method(D_METHOD("set_adjustment_contrast", "contrast"), &Environment::set_adjustment_contrast);
ClassDB::bind_method(D_METHOD("get_adjustment_contrast"), &Environment::get_adjustment_contrast);
-
ClassDB::bind_method(D_METHOD("set_adjustment_saturation", "saturation"), &Environment::set_adjustment_saturation);
ClassDB::bind_method(D_METHOD("get_adjustment_saturation"), &Environment::get_adjustment_saturation);
-
ClassDB::bind_method(D_METHOD("set_adjustment_color_correction", "color_correction"), &Environment::set_adjustment_color_correction);
ClassDB::bind_method(D_METHOD("get_adjustment_color_correction"), &Environment::get_adjustment_color_correction);
ADD_GROUP("Adjustments", "adjustment_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "adjustment_enabled"), "set_adjustment_enable", "is_adjustment_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_adjustment_color_correction", "get_adjustment_color_correction");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "adjustment_enabled"), "set_adjustment_enabled", "is_adjustment_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_adjustment_color_correction", "get_adjustment_color_correction");
+
+ // Constants
- BIND_ENUM_CONSTANT(BG_KEEP);
BIND_ENUM_CONSTANT(BG_CLEAR_COLOR);
BIND_ENUM_CONSTANT(BG_COLOR);
BIND_ENUM_CONSTANT(BG_SKY);
- BIND_ENUM_CONSTANT(BG_COLOR_SKY);
BIND_ENUM_CONSTANT(BG_CANVAS);
+ BIND_ENUM_CONSTANT(BG_KEEP);
BIND_ENUM_CONSTANT(BG_CAMERA_FEED);
BIND_ENUM_CONSTANT(BG_MAX);
- BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE);
- BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN);
- BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT);
- BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_BG);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_DISABLED);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_COLOR);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_SKY);
+
+ BIND_ENUM_CONSTANT(REFLECTION_SOURCE_BG);
+ BIND_ENUM_CONSTANT(REFLECTION_SOURCE_DISABLED);
+ BIND_ENUM_CONSTANT(REFLECTION_SOURCE_SKY);
BIND_ENUM_CONSTANT(TONE_MAPPER_LINEAR);
BIND_ENUM_CONSTANT(TONE_MAPPER_REINHARDT);
BIND_ENUM_CONSTANT(TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(TONE_MAPPER_ACES);
- BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW);
- BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM);
- BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_HIGH);
+ BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE);
+ BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN);
+ BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT);
+ BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE);
+ BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_MIX);
BIND_ENUM_CONSTANT(SSAO_BLUR_DISABLED);
BIND_ENUM_CONSTANT(SSAO_BLUR_1x1);
BIND_ENUM_CONSTANT(SSAO_BLUR_2x2);
BIND_ENUM_CONSTANT(SSAO_BLUR_3x3);
- BIND_ENUM_CONSTANT(SSAO_QUALITY_LOW);
- BIND_ENUM_CONSTANT(SSAO_QUALITY_MEDIUM);
- BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH);
-}
-
-Environment::Environment() :
- bg_mode(BG_CLEAR_COLOR),
- tone_mapper(TONE_MAPPER_LINEAR),
- ssao_blur(SSAO_BLUR_3x3),
- ssao_quality(SSAO_QUALITY_MEDIUM),
- glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE),
- dof_blur_far_quality(DOF_BLUR_QUALITY_LOW),
- dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) {
-
- environment = VS::get_singleton()->environment_create();
-
- bg_mode = BG_CLEAR_COLOR;
- bg_sky_custom_fov = 0;
- bg_sky_orientation = Basis();
- bg_energy = 1.0;
- bg_canvas_max_layer = 0;
- ambient_energy = 1.0;
- //ambient_sky_contribution = 1.0;
- set_ambient_light_sky_contribution(1.0);
- set_camera_feed_id(1);
-
- tone_mapper = TONE_MAPPER_LINEAR;
- tonemap_exposure = 1.0;
- tonemap_white = 1.0;
- tonemap_auto_exposure = false;
- tonemap_auto_exposure_max = 8;
- tonemap_auto_exposure_min = 0.05;
- tonemap_auto_exposure_speed = 0.5;
- tonemap_auto_exposure_grey = 0.4;
-
- set_tonemapper(tone_mapper); //update
-
- adjustment_enabled = false;
- adjustment_contrast = 1.0;
- adjustment_saturation = 1.0;
- adjustment_brightness = 1.0;
-
- set_adjustment_enable(adjustment_enabled); //update
-
- ssr_enabled = false;
- ssr_max_steps = 64;
- ssr_fade_in = 0.15;
- ssr_fade_out = 2.0;
- ssr_depth_tolerance = 0.2;
- ssr_roughness = true;
-
- ssao_enabled = false;
- ssao_radius = 1;
- ssao_intensity = 1;
- ssao_radius2 = 0;
- ssao_intensity2 = 1;
- ssao_bias = 0.01;
- ssao_direct_light_affect = 0.0;
- ssao_ao_channel_affect = 0.0;
- ssao_blur = SSAO_BLUR_3x3;
- set_ssao_edge_sharpness(4);
- set_ssao_quality(SSAO_QUALITY_MEDIUM);
-
- glow_enabled = false;
- glow_levels = (1 << 2) | (1 << 4);
- glow_intensity = 0.8;
- glow_strength = 1.0;
- glow_bloom = 0.0;
- glow_blend_mode = GLOW_BLEND_MODE_SOFTLIGHT;
- glow_hdr_bleed_threshold = 1.0;
- glow_hdr_luminance_cap = 12.0;
- glow_hdr_bleed_scale = 2.0;
- glow_bicubic_upscale = false;
-
- dof_blur_far_enabled = false;
- dof_blur_far_distance = 10;
- dof_blur_far_transition = 5;
- dof_blur_far_amount = 0.1;
- dof_blur_far_quality = DOF_BLUR_QUALITY_MEDIUM;
-
- dof_blur_near_enabled = false;
- dof_blur_near_distance = 2;
- dof_blur_near_transition = 1;
- dof_blur_near_amount = 0.1;
- dof_blur_near_quality = DOF_BLUR_QUALITY_MEDIUM;
-
- fog_enabled = false;
- fog_color = Color(0.5, 0.5, 0.5);
- fog_sun_color = Color(0.8, 0.8, 0.0);
- fog_sun_amount = 0;
-
- fog_depth_enabled = true;
-
- fog_depth_begin = 10;
- fog_depth_end = 100;
- fog_depth_curve = 1;
-
- fog_transmit_enabled = false;
- fog_transmit_curve = 1;
-
- fog_height_enabled = false;
- fog_height_min = 10;
- fog_height_max = 0;
- fog_height_curve = 1;
-
- set_fog_color(Color(0.5, 0.6, 0.7));
- set_fog_sun_color(Color(1.0, 0.9, 0.7));
+ BIND_ENUM_CONSTANT(SDFGI_CASCADES_4);
+ BIND_ENUM_CONSTANT(SDFGI_CASCADES_6);
+ BIND_ENUM_CONSTANT(SDFGI_CASCADES_8);
+
+ BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_DISABLED);
+ BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_75_PERCENT);
+ BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_50_PERCENT);
+
+ BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED);
+ BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_LOW);
+ BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM);
+ BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_HIGH);
+}
+
+Environment::Environment() {
+ environment = RS::get_singleton()->environment_create();
+
+ set_camera_feed_id(bg_camera_feed_id);
+ _update_ambient_light();
+ _update_tonemap();
+ _update_ssr();
+ _update_ssao();
+ _update_sdfgi();
+ _update_glow();
+ _update_fog();
+ _update_adjustment();
+ _update_volumetric_fog();
+ _change_notify();
}
Environment::~Environment() {
-
- VS::get_singleton()->free(environment);
+ RS::get_singleton()->free(environment);
}
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 62c6c5b4cd..d4d84f31aa 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -34,30 +34,59 @@
#include "core/resource.h"
#include "scene/resources/sky.h"
#include "scene/resources/texture.h"
-#include "servers/visual_server.h"
+#include "servers/rendering_server.h"
class Environment : public Resource {
-
GDCLASS(Environment, Resource);
public:
enum BGMode {
-
BG_CLEAR_COLOR,
BG_COLOR,
BG_SKY,
- BG_COLOR_SKY,
BG_CANVAS,
BG_KEEP,
BG_CAMERA_FEED,
BG_MAX
};
+ enum AmbientSource {
+ AMBIENT_SOURCE_BG,
+ AMBIENT_SOURCE_DISABLED,
+ AMBIENT_SOURCE_COLOR,
+ AMBIENT_SOURCE_SKY,
+ };
+
+ enum ReflectionSource {
+ REFLECTION_SOURCE_BG,
+ REFLECTION_SOURCE_DISABLED,
+ REFLECTION_SOURCE_SKY,
+ };
+
enum ToneMapper {
TONE_MAPPER_LINEAR,
TONE_MAPPER_REINHARDT,
TONE_MAPPER_FILMIC,
- TONE_MAPPER_ACES
+ TONE_MAPPER_ACES,
+ };
+
+ enum SSAOBlur {
+ SSAO_BLUR_DISABLED,
+ SSAO_BLUR_1x1,
+ SSAO_BLUR_2x2,
+ SSAO_BLUR_3x3,
+ };
+
+ enum SDFGICascades {
+ SDFGI_CASCADES_4,
+ SDFGI_CASCADES_6,
+ SDFGI_CASCADES_8,
+ };
+
+ enum SDFGIYScale {
+ SDFGI_Y_SCALE_DISABLED,
+ SDFGI_Y_SCALE_75_PERCENT,
+ SDFGI_Y_SCALE_50_PERCENT,
};
enum GlowBlendMode {
@@ -65,357 +94,323 @@ public:
GLOW_BLEND_MODE_SCREEN,
GLOW_BLEND_MODE_SOFTLIGHT,
GLOW_BLEND_MODE_REPLACE,
+ GLOW_BLEND_MODE_MIX,
};
- enum DOFBlurQuality {
- DOF_BLUR_QUALITY_LOW,
- DOF_BLUR_QUALITY_MEDIUM,
- DOF_BLUR_QUALITY_HIGH,
- };
-
- enum SSAOBlur {
- SSAO_BLUR_DISABLED,
- SSAO_BLUR_1x1,
- SSAO_BLUR_2x2,
- SSAO_BLUR_3x3
- };
-
- enum SSAOQuality {
- SSAO_QUALITY_LOW,
- SSAO_QUALITY_MEDIUM,
- SSAO_QUALITY_HIGH
+ enum VolumetricFogShadowFilter {
+ VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED,
+ VOLUMETRIC_FOG_SHADOW_FILTER_LOW,
+ VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM,
+ VOLUMETRIC_FOG_SHADOW_FILTER_HIGH,
};
private:
RID environment;
- BGMode bg_mode;
+ // Background
+ BGMode bg_mode = BG_CLEAR_COLOR;
Ref<Sky> bg_sky;
- float bg_sky_custom_fov;
- Basis bg_sky_orientation;
+ float bg_sky_custom_fov = 0;
+ Vector3 bg_sky_rotation;
Color bg_color;
- float bg_energy;
- int bg_canvas_max_layer;
+ float bg_energy = 1.0;
+ int bg_canvas_max_layer = 0;
+ int bg_camera_feed_id = 1;
+
+ // Ambient light
Color ambient_color;
- float ambient_energy;
- float ambient_sky_contribution;
- int camera_feed_id;
-
- ToneMapper tone_mapper;
- float tonemap_exposure;
- float tonemap_white;
- bool tonemap_auto_exposure;
- float tonemap_auto_exposure_max;
- float tonemap_auto_exposure_min;
- float tonemap_auto_exposure_speed;
- float tonemap_auto_exposure_grey;
-
- bool adjustment_enabled;
- float adjustment_contrast;
- float adjustment_saturation;
- float adjustment_brightness;
- Ref<Texture> adjustment_color_correction;
-
- bool ssr_enabled;
- int ssr_max_steps;
- float ssr_fade_in;
- float ssr_fade_out;
- float ssr_depth_tolerance;
- bool ssr_roughness;
-
- bool ssao_enabled;
- float ssao_radius;
- float ssao_intensity;
- float ssao_radius2;
- float ssao_intensity2;
- float ssao_bias;
- float ssao_direct_light_affect;
- float ssao_ao_channel_affect;
- Color ssao_color;
- SSAOBlur ssao_blur;
- float ssao_edge_sharpness;
- SSAOQuality ssao_quality;
-
- bool glow_enabled;
- int glow_levels;
- float glow_intensity;
- float glow_strength;
- float glow_bloom;
- GlowBlendMode glow_blend_mode;
- float glow_hdr_bleed_threshold;
- float glow_hdr_bleed_scale;
- float glow_hdr_luminance_cap;
- bool glow_bicubic_upscale;
-
- bool dof_blur_far_enabled;
- float dof_blur_far_distance;
- float dof_blur_far_transition;
- float dof_blur_far_amount;
- DOFBlurQuality dof_blur_far_quality;
-
- bool dof_blur_near_enabled;
- float dof_blur_near_distance;
- float dof_blur_near_transition;
- float dof_blur_near_amount;
- DOFBlurQuality dof_blur_near_quality;
-
- bool fog_enabled;
- Color fog_color;
- Color fog_sun_color;
- float fog_sun_amount;
-
- bool fog_depth_enabled;
- float fog_depth_begin;
- float fog_depth_end;
- float fog_depth_curve;
-
- bool fog_transmit_enabled;
- float fog_transmit_curve;
-
- bool fog_height_enabled;
- float fog_height_min;
- float fog_height_max;
- float fog_height_curve;
+ AmbientSource ambient_source = AMBIENT_SOURCE_BG;
+ float ambient_energy = 1.0;
+ float ambient_sky_contribution = 1.0;
+ ReflectionSource reflection_source = REFLECTION_SOURCE_BG;
+ Color ao_color;
+ void _update_ambient_light();
+
+ // Tonemap
+ ToneMapper tone_mapper = TONE_MAPPER_LINEAR;
+ float tonemap_exposure = 1.0;
+ float tonemap_white = 1.0;
+ bool tonemap_auto_exposure_enabled = false;
+ float tonemap_auto_exposure_min = 0.05;
+ float tonemap_auto_exposure_max = 8;
+ float tonemap_auto_exposure_speed = 0.5;
+ float tonemap_auto_exposure_grey = 0.4;
+ void _update_tonemap();
+
+ // SSR
+ bool ssr_enabled = false;
+ int ssr_max_steps = 64;
+ float ssr_fade_in = 0.15;
+ float ssr_fade_out = 2.0;
+ float ssr_depth_tolerance = 0.2;
+ void _update_ssr();
+
+ // SSAO
+ bool ssao_enabled = false;
+ float ssao_radius = 1.0;
+ float ssao_intensity = 1.0;
+ float ssao_bias = 0.01;
+ float ssao_direct_light_affect = 0.0;
+ float ssao_ao_channel_affect = 0.0;
+ SSAOBlur ssao_blur = SSAO_BLUR_3x3;
+ float ssao_edge_sharpness = 4.0;
+ void _update_ssao();
+
+ // SDFGI
+ bool sdfgi_enabled = false;
+ SDFGICascades sdfgi_cascades = SDFGI_CASCADES_6;
+ float sdfgi_min_cell_size = 0.2;
+ SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED;
+ bool sdfgi_use_occlusion = false;
+ bool sdfgi_use_multibounce = false;
+ bool sdfgi_read_sky_light = false;
+ float sdfgi_energy = 1.0;
+ float sdfgi_normal_bias = 1.1;
+ float sdfgi_probe_bias = 1.1;
+ void _update_sdfgi();
+
+ // Glow
+ bool glow_enabled = false;
+ int glow_levels = (1 << 2) | (1 << 4);
+ float glow_intensity = 0.8;
+ float glow_strength = 1.0;
+ float glow_mix = 0.05;
+ float glow_bloom = 0.0;
+ GlowBlendMode glow_blend_mode = GLOW_BLEND_MODE_SOFTLIGHT;
+ float glow_hdr_bleed_threshold = 1.0;
+ float glow_hdr_bleed_scale = 2.0;
+ float glow_hdr_luminance_cap = 12.0;
+ void _update_glow();
+
+ // Fog
+ bool fog_enabled = false;
+ Color fog_light_color = Color(0.5, 0.6, 0.7);
+ float fog_light_energy = 1.0;
+ float fog_sun_scatter = 0.0;
+ float fog_density = 0.001;
+ float fog_height = 0.0;
+ float fog_height_density = 0.0; //can be negative to invert effect
+
+ void _update_fog();
+
+ // Volumetric Fog
+ bool volumetric_fog_enabled = false;
+ float volumetric_fog_density = 0.01;
+ Color volumetric_fog_light = Color(0.0, 0.0, 0.0);
+ float volumetric_fog_light_energy = 1.0;
+ float volumetric_fog_length = 64.0;
+ float volumetric_fog_detail_spread = 2.0;
+ VolumetricFogShadowFilter volumetric_fog_shadow_filter = VOLUMETRIC_FOG_SHADOW_FILTER_LOW;
+ float volumetric_fog_gi_inject = 0.0;
+ void _update_volumetric_fog();
+
+ // Adjustment
+ bool adjustment_enabled = false;
+ float adjustment_brightness = 1.0;
+ float adjustment_contrast = 1.0;
+ float adjustment_saturation = 1.0;
+ Ref<Texture2D> adjustment_color_correction;
+ void _update_adjustment();
protected:
static void _bind_methods();
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
+ bool _set(const StringName &p_name, const Variant &p_value);
+#endif
public:
- void set_background(BGMode p_bg);
- void set_sky(const Ref<Sky> &p_sky);
- void set_sky_custom_fov(float p_scale);
- void set_sky_orientation(const Basis &p_orientation);
- void set_sky_rotation(const Vector3 &p_euler_rad);
- void set_sky_rotation_degrees(const Vector3 &p_euler_deg);
- void set_bg_color(const Color &p_color);
- void set_bg_energy(float p_energy);
- void set_canvas_max_layer(int p_max_layer);
- void set_ambient_light_color(const Color &p_color);
- void set_ambient_light_energy(float p_energy);
- void set_ambient_light_sky_contribution(float p_energy);
- void set_camera_feed_id(int p_camera_feed_id);
+ virtual RID get_rid() const override;
+ // Background
+ void set_background(BGMode p_bg);
BGMode get_background() const;
+ void set_sky(const Ref<Sky> &p_sky);
Ref<Sky> get_sky() const;
+ void set_sky_custom_fov(float p_scale);
float get_sky_custom_fov() const;
- Basis get_sky_orientation() const;
+ void set_sky_rotation(const Vector3 &p_rotation);
Vector3 get_sky_rotation() const;
- Vector3 get_sky_rotation_degrees() const;
+ void set_bg_color(const Color &p_color);
Color get_bg_color() const;
+ void set_bg_energy(float p_energy);
float get_bg_energy() const;
+ void set_canvas_max_layer(int p_max_layer);
int get_canvas_max_layer() const;
+ void set_camera_feed_id(int p_id);
+ int get_camera_feed_id() const;
+
+ // Ambient light
+ void set_ambient_light_color(const Color &p_color);
Color get_ambient_light_color() const;
+ void set_ambient_source(AmbientSource p_source);
+ AmbientSource get_ambient_source() const;
+ void set_ambient_light_energy(float p_energy);
float get_ambient_light_energy() const;
+ void set_ambient_light_sky_contribution(float p_ratio);
float get_ambient_light_sky_contribution() const;
- int get_camera_feed_id(void) const;
+ void set_reflection_source(ReflectionSource p_source);
+ ReflectionSource get_reflection_source() const;
+ void set_ao_color(const Color &p_color);
+ Color get_ao_color() const;
+ // Tonemap
void set_tonemapper(ToneMapper p_tone_mapper);
ToneMapper get_tonemapper() const;
-
void set_tonemap_exposure(float p_exposure);
float get_tonemap_exposure() const;
-
void set_tonemap_white(float p_white);
float get_tonemap_white() const;
-
- void set_tonemap_auto_exposure(bool p_enabled);
- bool get_tonemap_auto_exposure() const;
-
- void set_tonemap_auto_exposure_max(float p_auto_exposure_max);
- float get_tonemap_auto_exposure_max() const;
-
+ void set_tonemap_auto_exposure_enabled(bool p_enabled);
+ bool is_tonemap_auto_exposure_enabled() const;
void set_tonemap_auto_exposure_min(float p_auto_exposure_min);
float get_tonemap_auto_exposure_min() const;
-
+ void set_tonemap_auto_exposure_max(float p_auto_exposure_max);
+ float get_tonemap_auto_exposure_max() const;
void set_tonemap_auto_exposure_speed(float p_auto_exposure_speed);
float get_tonemap_auto_exposure_speed() const;
-
void set_tonemap_auto_exposure_grey(float p_auto_exposure_grey);
float get_tonemap_auto_exposure_grey() const;
- void set_adjustment_enable(bool p_enable);
- bool is_adjustment_enabled() const;
-
- void set_adjustment_brightness(float p_brightness);
- float get_adjustment_brightness() const;
-
- void set_adjustment_contrast(float p_contrast);
- float get_adjustment_contrast() const;
-
- void set_adjustment_saturation(float p_saturation);
- float get_adjustment_saturation() const;
-
- void set_adjustment_color_correction(const Ref<Texture> &p_ramp);
- Ref<Texture> get_adjustment_color_correction() const;
-
- void set_ssr_enabled(bool p_enable);
+ // SSR
+ void set_ssr_enabled(bool p_enabled);
bool is_ssr_enabled() const;
-
void set_ssr_max_steps(int p_steps);
int get_ssr_max_steps() const;
-
void set_ssr_fade_in(float p_fade_in);
float get_ssr_fade_in() const;
-
void set_ssr_fade_out(float p_fade_out);
float get_ssr_fade_out() const;
-
void set_ssr_depth_tolerance(float p_depth_tolerance);
float get_ssr_depth_tolerance() const;
- void set_ssr_rough(bool p_enable);
- bool is_ssr_rough() const;
-
- void set_ssao_enabled(bool p_enable);
+ // SSAO
+ void set_ssao_enabled(bool p_enabled);
bool is_ssao_enabled() const;
-
void set_ssao_radius(float p_radius);
float get_ssao_radius() const;
-
void set_ssao_intensity(float p_intensity);
float get_ssao_intensity() const;
-
- void set_ssao_radius2(float p_radius);
- float get_ssao_radius2() const;
-
- void set_ssao_intensity2(float p_intensity);
- float get_ssao_intensity2() const;
-
void set_ssao_bias(float p_bias);
float get_ssao_bias() const;
-
void set_ssao_direct_light_affect(float p_direct_light_affect);
float get_ssao_direct_light_affect() const;
-
void set_ssao_ao_channel_affect(float p_ao_channel_affect);
float get_ssao_ao_channel_affect() const;
-
- void set_ssao_color(const Color &p_color);
- Color get_ssao_color() const;
-
void set_ssao_blur(SSAOBlur p_blur);
SSAOBlur get_ssao_blur() const;
-
- void set_ssao_quality(SSAOQuality p_quality);
- SSAOQuality get_ssao_quality() const;
-
void set_ssao_edge_sharpness(float p_edge_sharpness);
float get_ssao_edge_sharpness() const;
+ // SDFGI
+ void set_sdfgi_enabled(bool p_enabled);
+ bool is_sdfgi_enabled() const;
+ void set_sdfgi_cascades(SDFGICascades p_cascades);
+ SDFGICascades get_sdfgi_cascades() const;
+ void set_sdfgi_min_cell_size(float p_size);
+ float get_sdfgi_min_cell_size() const;
+ void set_sdfgi_max_distance(float p_distance);
+ float get_sdfgi_max_distance() const;
+ void set_sdfgi_cascade0_distance(float p_distance);
+ float get_sdfgi_cascade0_distance() const;
+ void set_sdfgi_y_scale(SDFGIYScale p_y_scale);
+ SDFGIYScale get_sdfgi_y_scale() const;
+ void set_sdfgi_use_occlusion(bool p_enabled);
+ bool is_sdfgi_using_occlusion() const;
+ void set_sdfgi_use_multi_bounce(bool p_enabled);
+ bool is_sdfgi_using_multi_bounce() const;
+ void set_sdfgi_read_sky_light(bool p_enabled);
+ bool is_sdfgi_reading_sky_light() const;
+ void set_sdfgi_energy(float p_energy);
+ float get_sdfgi_energy() const;
+ void set_sdfgi_normal_bias(float p_bias);
+ float get_sdfgi_normal_bias() const;
+ void set_sdfgi_probe_bias(float p_bias);
+ float get_sdfgi_probe_bias() const;
+
+ // Glow
void set_glow_enabled(bool p_enabled);
bool is_glow_enabled() const;
-
- void set_glow_level(int p_level, bool p_enabled);
+ void set_glow_level_enabled(int p_level, bool p_enabled);
bool is_glow_level_enabled(int p_level) const;
-
void set_glow_intensity(float p_intensity);
float get_glow_intensity() const;
-
void set_glow_strength(float p_strength);
float get_glow_strength() const;
-
+ void set_glow_mix(float p_mix);
+ float get_glow_mix() const;
void set_glow_bloom(float p_threshold);
float get_glow_bloom() const;
-
void set_glow_blend_mode(GlowBlendMode p_mode);
GlowBlendMode get_glow_blend_mode() const;
-
void set_glow_hdr_bleed_threshold(float p_threshold);
float get_glow_hdr_bleed_threshold() const;
-
- void set_glow_hdr_luminance_cap(float p_amount);
- float get_glow_hdr_luminance_cap() const;
-
void set_glow_hdr_bleed_scale(float p_scale);
float get_glow_hdr_bleed_scale() const;
+ void set_glow_hdr_luminance_cap(float p_amount);
+ float get_glow_hdr_luminance_cap() const;
- void set_glow_bicubic_upscale(bool p_enable);
- bool is_glow_bicubic_upscale_enabled() const;
-
- void set_dof_blur_far_enabled(bool p_enable);
- bool is_dof_blur_far_enabled() const;
-
- void set_dof_blur_far_distance(float p_distance);
- float get_dof_blur_far_distance() const;
-
- void set_dof_blur_far_transition(float p_distance);
- float get_dof_blur_far_transition() const;
-
- void set_dof_blur_far_amount(float p_amount);
- float get_dof_blur_far_amount() const;
-
- void set_dof_blur_far_quality(DOFBlurQuality p_quality);
- DOFBlurQuality get_dof_blur_far_quality() const;
-
- void set_dof_blur_near_enabled(bool p_enable);
- bool is_dof_blur_near_enabled() const;
-
- void set_dof_blur_near_distance(float p_distance);
- float get_dof_blur_near_distance() const;
-
- void set_dof_blur_near_transition(float p_distance);
- float get_dof_blur_near_transition() const;
-
- void set_dof_blur_near_amount(float p_amount);
- float get_dof_blur_near_amount() const;
-
- void set_dof_blur_near_quality(DOFBlurQuality p_quality);
- DOFBlurQuality get_dof_blur_near_quality() const;
+ // Fog
void set_fog_enabled(bool p_enabled);
bool is_fog_enabled() const;
-
- void set_fog_color(const Color &p_color);
- Color get_fog_color() const;
-
- void set_fog_sun_color(const Color &p_color);
- Color get_fog_sun_color() const;
-
- void set_fog_sun_amount(float p_amount);
- float get_fog_sun_amount() const;
-
- void set_fog_depth_enabled(bool p_enabled);
- bool is_fog_depth_enabled() const;
-
- void set_fog_depth_begin(float p_distance);
- float get_fog_depth_begin() const;
-
- void set_fog_depth_end(float p_distance);
- float get_fog_depth_end() const;
-
- void set_fog_depth_curve(float p_curve);
- float get_fog_depth_curve() const;
-
- void set_fog_transmit_enabled(bool p_enabled);
- bool is_fog_transmit_enabled() const;
-
- void set_fog_transmit_curve(float p_curve);
- float get_fog_transmit_curve() const;
-
- void set_fog_height_enabled(bool p_enabled);
- bool is_fog_height_enabled() const;
-
- void set_fog_height_min(float p_distance);
- float get_fog_height_min() const;
-
- void set_fog_height_max(float p_distance);
- float get_fog_height_max() const;
-
- void set_fog_height_curve(float p_distance);
- float get_fog_height_curve() const;
-
- virtual RID get_rid() const;
+ void set_fog_light_color(const Color &p_light_color);
+ Color get_fog_light_color() const;
+ void set_fog_light_energy(float p_amount);
+ float get_fog_light_energy() const;
+ void set_fog_sun_scatter(float p_amount);
+ float get_fog_sun_scatter() const;
+
+ void set_fog_density(float p_amount);
+ float get_fog_density() const;
+ void set_fog_height(float p_amount);
+ float get_fog_height() const;
+ void set_fog_height_density(float p_amount);
+ float get_fog_height_density() const;
+
+ // Volumetric Fog
+ void set_volumetric_fog_enabled(bool p_enable);
+ bool is_volumetric_fog_enabled() const;
+ void set_volumetric_fog_density(float p_density);
+ float get_volumetric_fog_density() const;
+ void set_volumetric_fog_light(Color p_color);
+ Color get_volumetric_fog_light() const;
+ void set_volumetric_fog_light_energy(float p_begin);
+ float get_volumetric_fog_light_energy() const;
+ void set_volumetric_fog_length(float p_length);
+ float get_volumetric_fog_length() const;
+ void set_volumetric_fog_detail_spread(float p_detail_spread);
+ float get_volumetric_fog_detail_spread() const;
+ void set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter);
+ VolumetricFogShadowFilter get_volumetric_fog_shadow_filter() const;
+ void set_volumetric_fog_gi_inject(float p_gi_inject);
+ float get_volumetric_fog_gi_inject() const;
+
+ // Adjustment
+ void set_adjustment_enabled(bool p_enabled);
+ bool is_adjustment_enabled() const;
+ void set_adjustment_brightness(float p_brightness);
+ float get_adjustment_brightness() const;
+ void set_adjustment_contrast(float p_contrast);
+ float get_adjustment_contrast() const;
+ void set_adjustment_saturation(float p_saturation);
+ float get_adjustment_saturation() const;
+ void set_adjustment_color_correction(const Ref<Texture2D> &p_ramp);
+ Ref<Texture2D> get_adjustment_color_correction() const;
Environment();
~Environment();
};
VARIANT_ENUM_CAST(Environment::BGMode)
+VARIANT_ENUM_CAST(Environment::AmbientSource)
+VARIANT_ENUM_CAST(Environment::ReflectionSource)
VARIANT_ENUM_CAST(Environment::ToneMapper)
-VARIANT_ENUM_CAST(Environment::GlowBlendMode)
-VARIANT_ENUM_CAST(Environment::DOFBlurQuality)
-VARIANT_ENUM_CAST(Environment::SSAOQuality)
VARIANT_ENUM_CAST(Environment::SSAOBlur)
+VARIANT_ENUM_CAST(Environment::SDFGICascades)
+VARIANT_ENUM_CAST(Environment::SDFGIYScale)
+VARIANT_ENUM_CAST(Environment::GlowBlendMode)
+VARIANT_ENUM_CAST(Environment::VolumetricFogShadowFilter)
#endif // ENVIRONMENT_H
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 19c59b3817..7cc39f661d 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -65,11 +65,11 @@ void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, co
int chars_drawn = 0;
bool with_outline = has_outline();
for (int i = 0; i < p_text.length(); i++) {
-
int width = get_char_size(p_text[i]).width;
- if (p_clip_w >= 0 && (ofs.x + width) > p_clip_w)
+ if (p_clip_w >= 0 && (ofs.x + width) > p_clip_w) {
break; //clip
+ }
ofs.x += draw_char(p_canvas_item, p_pos + ofs, p_text[i], p_text[i + 1], with_outline ? p_outline_modulate : p_modulate, with_outline);
++chars_drawn;
@@ -84,17 +84,16 @@ void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, co
}
void Font::update_changes() {
-
emit_changed();
}
void Font::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "string", "modulate", "clip_w", "outline_modulate"), &Font::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(-1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("get_ascent"), &Font::get_ascent);
ClassDB::bind_method(D_METHOD("get_descent"), &Font::get_descent);
ClassDB::bind_method(D_METHOD("get_height"), &Font::get_height);
ClassDB::bind_method(D_METHOD("is_distance_field_hint"), &Font::is_distance_field_hint);
+ ClassDB::bind_method(D_METHOD("get_char_size", "char", "next"), &Font::get_char_size, DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_string_size", "string"), &Font::get_string_size);
ClassDB::bind_method(D_METHOD("get_wordwrap_string_size", "string", "width"), &Font::get_wordwrap_string_size);
ClassDB::bind_method(D_METHOD("has_outline"), &Font::has_outline);
@@ -107,33 +106,30 @@ Font::Font() {
/////////////////////////////////////////////////////////////////
-void BitmapFont::_set_chars(const PoolVector<int> &p_chars) {
-
+void BitmapFont::_set_chars(const Vector<int> &p_chars) {
int len = p_chars.size();
//char 1 charsize 1 texture, 4 rect, 2 align, advance 1
ERR_FAIL_COND(len % 9);
- if (!len)
+ if (!len) {
return; //none to do
+ }
int chars = len / 9;
- PoolVector<int>::Read r = p_chars.read();
+ const int *r = p_chars.ptr();
for (int i = 0; i < chars; i++) {
-
const int *data = &r[i * 9];
add_char(data[0], data[1], Rect2(data[2], data[3], data[4], data[5]), Size2(data[6], data[7]), data[8]);
}
}
-PoolVector<int> BitmapFont::_get_chars() const {
+Vector<int> BitmapFont::_get_chars() const {
+ Vector<int> chars;
- PoolVector<int> chars;
-
- const CharType *key = NULL;
+ const char32_t *key = nullptr;
while ((key = char_map.next(key))) {
-
const Character *c = char_map.getptr(*key);
- ERR_FAIL_COND_V(!c, PoolVector<int>());
+ ERR_FAIL_COND_V(!c, Vector<int>());
chars.push_back(*key);
chars.push_back(c->texture_idx);
chars.push_back(c->rect.position.x);
@@ -149,27 +145,24 @@ PoolVector<int> BitmapFont::_get_chars() const {
return chars;
}
-void BitmapFont::_set_kernings(const PoolVector<int> &p_kernings) {
-
+void BitmapFont::_set_kernings(const Vector<int> &p_kernings) {
int len = p_kernings.size();
ERR_FAIL_COND(len % 3);
- if (!len)
+ if (!len) {
return;
- PoolVector<int>::Read r = p_kernings.read();
+ }
+ const int *r = p_kernings.ptr();
for (int i = 0; i < len / 3; i++) {
-
const int *data = &r[i * 3];
add_kerning_pair(data[0], data[1], data[2]);
}
}
-PoolVector<int> BitmapFont::_get_kernings() const {
-
- PoolVector<int> kernings;
+Vector<int> BitmapFont::_get_kernings() const {
+ Vector<int> kernings;
for (Map<KerningPairKey, int>::Element *E = kerning_map.front(); E; E = E->next()) {
-
kernings.push_back(E->key().A);
kernings.push_back(E->key().B);
kernings.push_back(E->get());
@@ -179,20 +172,19 @@ PoolVector<int> BitmapFont::_get_kernings() const {
}
void BitmapFont::_set_textures(const Vector<Variant> &p_textures) {
-
textures.clear();
for (int i = 0; i < p_textures.size(); i++) {
- Ref<Texture> tex = p_textures[i];
+ Ref<Texture2D> tex = p_textures[i];
ERR_CONTINUE(!tex.is_valid());
add_texture(tex);
}
}
Vector<Variant> BitmapFont::_get_textures() const {
-
Vector<Variant> rtextures;
- for (int i = 0; i < textures.size(); i++)
- rtextures.push_back(textures[i].get_ref_ptr());
+ for (int i = 0; i < textures.size(); i++) {
+ rtextures.push_back(textures[i]);
+ }
return rtextures;
}
@@ -207,7 +199,6 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
clear();
while (true) {
-
String line = f->get_line();
int delimiter = line.find(" ");
@@ -215,62 +206,65 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
int pos = delimiter + 1;
Map<String, String> keys;
- while (pos < line.size() && line[pos] == ' ')
+ while (pos < line.size() && line[pos] == ' ') {
pos++;
+ }
while (pos < line.size()) {
-
int eq = line.find("=", pos);
- if (eq == -1)
+ if (eq == -1) {
break;
+ }
String key = line.substr(pos, eq - pos);
int end = -1;
String value;
if (line[eq + 1] == '"') {
end = line.find("\"", eq + 2);
- if (end == -1)
+ if (end == -1) {
break;
+ }
value = line.substr(eq + 2, end - 1 - eq - 1);
pos = end + 1;
} else {
end = line.find(" ", eq + 1);
- if (end == -1)
+ if (end == -1) {
end = line.size();
+ }
value = line.substr(eq + 1, end - eq);
pos = end;
}
- while (pos < line.size() && line[pos] == ' ')
+ while (pos < line.size() && line[pos] == ' ') {
pos++;
+ }
keys[key] = value;
}
if (type == "info") {
-
- if (keys.has("face"))
+ if (keys.has("face")) {
set_name(keys["face"]);
+ }
/*
if (keys.has("size"))
font->set_height(keys["size"].to_int());
*/
} else if (type == "common") {
-
- if (keys.has("lineHeight"))
+ if (keys.has("lineHeight")) {
set_height(keys["lineHeight"].to_int());
- if (keys.has("base"))
+ }
+ if (keys.has("base")) {
set_ascent(keys["base"].to_int());
+ }
} else if (type == "page") {
-
if (keys.has("file")) {
-
String base_dir = p_file.get_base_dir();
String file = base_dir.plus_file(keys["file"]);
- Ref<Texture> tex = ResourceLoader::load(file);
+ Ref<Texture2D> tex = ResourceLoader::load(file);
if (tex.is_null()) {
ERR_PRINT("Can't load font texture!");
} else {
@@ -278,55 +272,66 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
}
}
} else if (type == "char") {
-
- CharType idx = 0;
- if (keys.has("id"))
+ char32_t idx = 0;
+ if (keys.has("id")) {
idx = keys["id"].to_int();
+ }
Rect2 rect;
- if (keys.has("x"))
+ if (keys.has("x")) {
rect.position.x = keys["x"].to_int();
- if (keys.has("y"))
+ }
+ if (keys.has("y")) {
rect.position.y = keys["y"].to_int();
- if (keys.has("width"))
+ }
+ if (keys.has("width")) {
rect.size.width = keys["width"].to_int();
- if (keys.has("height"))
+ }
+ if (keys.has("height")) {
rect.size.height = keys["height"].to_int();
+ }
Point2 ofs;
- if (keys.has("xoffset"))
+ if (keys.has("xoffset")) {
ofs.x = keys["xoffset"].to_int();
- if (keys.has("yoffset"))
+ }
+ if (keys.has("yoffset")) {
ofs.y = keys["yoffset"].to_int();
+ }
int texture = 0;
- if (keys.has("page"))
+ if (keys.has("page")) {
texture = keys["page"].to_int();
+ }
int advance = -1;
- if (keys.has("xadvance"))
+ if (keys.has("xadvance")) {
advance = keys["xadvance"].to_int();
+ }
add_char(idx, texture, rect, ofs, advance);
} else if (type == "kerning") {
-
- CharType first = 0, second = 0;
+ char32_t first = 0, second = 0;
int k = 0;
- if (keys.has("first"))
+ if (keys.has("first")) {
first = keys["first"].to_int();
- if (keys.has("second"))
+ }
+ if (keys.has("second")) {
second = keys["second"].to_int();
- if (keys.has("amount"))
+ }
+ if (keys.has("amount")) {
k = keys["amount"].to_int();
+ }
add_kerning_pair(first, second, -k);
}
- if (f->eof_reached())
+ if (f->eof_reached()) {
break;
+ }
}
memdelete(f);
@@ -335,65 +340,64 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
}
void BitmapFont::set_height(float p_height) {
-
height = p_height;
}
-float BitmapFont::get_height() const {
+float BitmapFont::get_height() const {
return height;
}
void BitmapFont::set_ascent(float p_ascent) {
-
ascent = p_ascent;
}
-float BitmapFont::get_ascent() const {
+float BitmapFont::get_ascent() const {
return ascent;
}
-float BitmapFont::get_descent() const {
+float BitmapFont::get_descent() const {
return height - ascent;
}
-void BitmapFont::add_texture(const Ref<Texture> &p_texture) {
+float BitmapFont::get_underline_position() const {
+ return 2;
+}
+float BitmapFont::get_underline_thickness() const {
+ return 1;
+}
+
+void BitmapFont::add_texture(const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object.");
textures.push_back(p_texture);
}
int BitmapFont::get_texture_count() const {
-
return textures.size();
};
-Ref<Texture> BitmapFont::get_texture(int p_idx) const {
-
- ERR_FAIL_INDEX_V(p_idx, textures.size(), Ref<Texture>());
+Ref<Texture2D> BitmapFont::get_texture(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, textures.size(), Ref<Texture2D>());
return textures[p_idx];
};
int BitmapFont::get_character_count() const {
-
return char_map.size();
};
-Vector<CharType> BitmapFont::get_char_keys() const {
-
- Vector<CharType> chars;
+Vector<char32_t> BitmapFont::get_char_keys() const {
+ Vector<char32_t> chars;
chars.resize(char_map.size());
- const CharType *ct = NULL;
+ const char32_t *ct = nullptr;
int count = 0;
while ((ct = char_map.next(ct))) {
-
chars.write[count++] = *ct;
};
return chars;
};
-BitmapFont::Character BitmapFont::get_character(CharType p_char) const {
-
+BitmapFont::Character BitmapFont::get_character(char32_t p_char) const {
if (!char_map.has(p_char)) {
ERR_FAIL_V(Character());
};
@@ -401,10 +405,10 @@ BitmapFont::Character BitmapFont::get_character(CharType p_char) const {
return char_map[p_char];
};
-void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
-
- if (p_advance < 0)
+void BitmapFont::add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+ if (p_advance < 0) {
p_advance = p_rect.size.width;
+ }
Character c;
c.rect = p_rect;
@@ -416,23 +420,19 @@ void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rec
char_map[p_char] = c;
}
-void BitmapFont::add_kerning_pair(CharType p_A, CharType p_B, int p_kerning) {
-
+void BitmapFont::add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) {
KerningPairKey kpk;
kpk.A = p_A;
kpk.B = p_B;
if (p_kerning == 0 && kerning_map.has(kpk)) {
-
kerning_map.erase(kpk);
} else {
-
kerning_map[kpk] = p_kerning;
}
}
Vector<BitmapFont::KerningPairKey> BitmapFont::get_kerning_pair_keys() const {
-
Vector<BitmapFont::KerningPairKey> ret;
ret.resize(kerning_map.size());
int i = 0;
@@ -444,32 +444,29 @@ Vector<BitmapFont::KerningPairKey> BitmapFont::get_kerning_pair_keys() const {
return ret;
}
-int BitmapFont::get_kerning_pair(CharType p_A, CharType p_B) const {
-
+int BitmapFont::get_kerning_pair(char32_t p_A, char32_t p_B) const {
KerningPairKey kpk;
kpk.A = p_A;
kpk.B = p_B;
const Map<KerningPairKey, int>::Element *E = kerning_map.find(kpk);
- if (E)
+ if (E) {
return E->get();
+ }
return 0;
}
void BitmapFont::set_distance_field_hint(bool p_distance_field) {
-
distance_field_hint = p_distance_field;
emit_changed();
}
bool BitmapFont::is_distance_field_hint() const {
-
return distance_field_hint;
}
void BitmapFont::clear() {
-
height = 1;
ascent = 0;
char_map.clear();
@@ -479,16 +476,15 @@ void BitmapFont::clear() {
}
Size2 Font::get_string_size(const String &p_string) const {
-
float w = 0;
int l = p_string.length();
- if (l == 0)
+ if (l == 0) {
return Size2(0, get_height());
- const CharType *sptr = &p_string[0];
+ }
+ const char32_t *sptr = &p_string[0];
for (int i = 0; i < l; i++) {
-
w += get_char_size(sptr[i], sptr[i + 1]).width;
}
@@ -496,12 +492,12 @@ Size2 Font::get_string_size(const String &p_string) const {
}
Size2 Font::get_wordwrap_string_size(const String &p_string, float p_width) const {
-
ERR_FAIL_COND_V(p_width <= 0, Vector2(0, get_height()));
int l = p_string.length();
- if (l == 0)
+ if (l == 0) {
return Size2(p_width, get_height());
+ }
float line_w = 0;
float h = 0;
@@ -527,8 +523,7 @@ Size2 Font::get_wordwrap_string_size(const String &p_string, float p_width) cons
}
void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) {
-
- for (Ref<BitmapFont> fallback_child = p_fallback; fallback_child != NULL; fallback_child = fallback_child->get_fallback()) {
+ for (Ref<BitmapFont> fallback_child = p_fallback; fallback_child != nullptr; fallback_child = fallback_child->get_fallback()) {
ERR_FAIL_COND_MSG(fallback_child == this, "Can't set as fallback one of its parents to prevent crashes due to recursive loop.");
}
@@ -536,17 +531,16 @@ void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) {
}
Ref<BitmapFont> BitmapFont::get_fallback() const {
-
return fallback;
}
-float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const {
-
+float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, bool p_outline) const {
const Character *c = char_map.getptr(p_char);
if (!c) {
- if (fallback.is_valid())
+ if (fallback.is_valid()) {
return fallback->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate, p_outline);
+ }
return 0;
}
@@ -556,33 +550,31 @@ float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_c
cpos.x += c->h_align;
cpos.y -= ascent;
cpos.y += c->v_align;
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), false);
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), RID(), Color(1, 1, 1, 1), false);
}
return get_char_size(p_char, p_next).width;
}
-Size2 BitmapFont::get_char_size(CharType p_char, CharType p_next) const {
-
+Size2 BitmapFont::get_char_size(char32_t p_char, char32_t p_next) const {
const Character *c = char_map.getptr(p_char);
if (!c) {
- if (fallback.is_valid())
+ if (fallback.is_valid()) {
return fallback->get_char_size(p_char, p_next);
+ }
return Size2();
}
Size2 ret(c->advance, c->rect.size.y);
if (p_next) {
-
KerningPairKey kpk;
kpk.A = p_char;
kpk.B = p_next;
const Map<KerningPairKey, int>::Element *E = kerning_map.find(kpk);
if (E) {
-
ret.width -= E->get();
}
}
@@ -591,7 +583,6 @@ Size2 BitmapFont::get_char_size(CharType p_char, CharType p_next) const {
}
void BitmapFont::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_from_fnt", "path"), &BitmapFont::create_from_fnt);
ClassDB::bind_method(D_METHOD("set_height", "px"), &BitmapFont::set_height);
@@ -606,8 +597,6 @@ void BitmapFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_count"), &BitmapFont::get_texture_count);
ClassDB::bind_method(D_METHOD("get_texture", "idx"), &BitmapFont::get_texture);
- ClassDB::bind_method(D_METHOD("get_char_size", "char", "next"), &BitmapFont::get_char_size, DEFVAL(0));
-
ClassDB::bind_method(D_METHOD("set_distance_field_hint", "enable"), &BitmapFont::set_distance_field_hint);
ClassDB::bind_method(D_METHOD("clear"), &BitmapFont::clear);
@@ -625,31 +614,29 @@ void BitmapFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_fallback"), &BitmapFont::get_fallback);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_textures", "_get_textures");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "chars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_chars", "_get_chars");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "kernings", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_kernings", "_get_kernings");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "chars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_chars", "_get_chars");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "kernings", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_kernings", "_get_kernings");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "1,1024,1"), "set_height", "get_height");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ascent", PROPERTY_HINT_RANGE, "0,1024,1"), "set_ascent", "get_ascent");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "1,1024,1"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ascent", PROPERTY_HINT_RANGE, "0,1024,1"), "set_ascent", "get_ascent");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_field"), "set_distance_field_hint", "is_distance_field_hint");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback", PROPERTY_HINT_RESOURCE_TYPE, "BitmapFont"), "set_fallback", "get_fallback");
}
BitmapFont::BitmapFont() {
-
clear();
}
BitmapFont::~BitmapFont() {
-
clear();
}
////////////
-RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error) {
-
- if (r_error)
+RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
Ref<BitmapFont> font;
font.instance();
@@ -657,8 +644,9 @@ RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_origi
Error err = font->create_from_fnt(p_path);
if (err) {
- if (r_error)
+ if (r_error) {
*r_error = err;
+ }
return RES();
}
@@ -666,19 +654,17 @@ RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_origi
}
void ResourceFormatLoaderBMFont::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("fnt");
}
bool ResourceFormatLoaderBMFont::handles_type(const String &p_type) const {
-
return (p_type == "BitmapFont");
}
String ResourceFormatLoaderBMFont::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "fnt")
+ if (el == "fnt") {
return "BitmapFont";
+ }
return "";
}
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 411145c153..c739520da3 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -36,7 +36,6 @@
#include "scene/resources/texture.h"
class Font : public Resource {
-
GDCLASS(Font, Resource);
protected:
@@ -47,8 +46,10 @@ public:
virtual float get_ascent() const = 0;
virtual float get_descent() const = 0;
+ virtual float get_underline_position() const = 0;
+ virtual float get_underline_thickness() const = 0;
- virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const = 0;
+ virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const = 0;
Size2 get_string_size(const String &p_string) const;
Size2 get_wordwrap_string_size(const String &p_string, float p_width) const;
@@ -58,7 +59,7 @@ public:
void draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate = Color(1, 1, 1), const Color &p_outline_modulate = Color(1, 1, 1)) const;
virtual bool has_outline() const { return false; }
- virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const = 0;
+ virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const = 0;
void update_changes();
Font();
@@ -73,8 +74,8 @@ class FontDrawer {
struct PendingDraw {
RID canvas_item;
Point2 pos;
- CharType chr;
- CharType next;
+ char32_t chr;
+ char32_t next;
Color modulate;
};
@@ -87,7 +88,7 @@ public:
has_outline = p_font->has_outline();
}
- float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1)) {
+ float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1)) {
if (has_outline) {
PendingDraw draw = { p_canvas_item, p_pos, p_char, p_next, p_modulate };
pending_draws.push_back(draw);
@@ -104,15 +105,13 @@ public:
};
class BitmapFont : public Font {
-
GDCLASS(BitmapFont, Font);
RES_BASE_EXTENSION("font");
- Vector<Ref<Texture> > textures;
+ Vector<Ref<Texture2D>> textures;
public:
struct Character {
-
int texture_idx;
Rect2 rect;
float v_align;
@@ -126,7 +125,6 @@ public:
};
struct KerningPairKey {
-
union {
struct {
uint32_t A, B;
@@ -139,17 +137,17 @@ public:
};
private:
- HashMap<CharType, Character> char_map;
+ HashMap<char32_t, Character> char_map;
Map<KerningPairKey, int> kerning_map;
float height;
float ascent;
bool distance_field_hint;
- void _set_chars(const PoolVector<int> &p_chars);
- PoolVector<int> _get_chars() const;
- void _set_kernings(const PoolVector<int> &p_kernings);
- PoolVector<int> _get_kernings() const;
+ void _set_chars(const Vector<int> &p_chars);
+ Vector<int> _get_chars() const;
+ void _set_kernings(const Vector<int> &p_kernings);
+ Vector<int> _get_kernings() const;
void _set_textures(const Vector<Variant> &p_textures);
Vector<Variant> _get_textures() const;
@@ -162,27 +160,29 @@ public:
Error create_from_fnt(const String &p_file);
void set_height(float p_height);
- float get_height() const;
+ float get_height() const override;
void set_ascent(float p_ascent);
- float get_ascent() const;
- float get_descent() const;
+ float get_ascent() const override;
+ float get_descent() const override;
+ float get_underline_position() const override;
+ float get_underline_thickness() const override;
- void add_texture(const Ref<Texture> &p_texture);
- void add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);
+ void add_texture(const Ref<Texture2D> &p_texture);
+ void add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);
int get_character_count() const;
- Vector<CharType> get_char_keys() const;
- Character get_character(CharType p_char) const;
+ Vector<char32_t> get_char_keys() const;
+ Character get_character(char32_t p_char) const;
int get_texture_count() const;
- Ref<Texture> get_texture(int p_idx) const;
+ Ref<Texture2D> get_texture(int p_idx) const;
- void add_kerning_pair(CharType p_A, CharType p_B, int p_kerning);
- int get_kerning_pair(CharType p_A, CharType p_B) const;
+ void add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning);
+ int get_kerning_pair(char32_t p_A, char32_t p_B) const;
Vector<KerningPairKey> get_kerning_pair_keys() const;
- Size2 get_char_size(CharType p_char, CharType p_next = 0) const;
+ Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const override;
void set_fallback(const Ref<BitmapFont> &p_fallback);
Ref<BitmapFont> get_fallback() const;
@@ -190,9 +190,9 @@ public:
void clear();
void set_distance_field_hint(bool p_distance_field);
- bool is_distance_field_hint() const;
+ bool is_distance_field_hint() const override;
- float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const;
+ float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override;
BitmapFont();
~BitmapFont();
@@ -200,7 +200,7 @@ public:
class ResourceFormatLoaderBMFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp
index 6373436762..b720653f91 100644
--- a/scene/resources/gradient.cpp
+++ b/scene/resources/gradient.cpp
@@ -52,7 +52,6 @@ Gradient::~Gradient() {
}
void Gradient::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &Gradient::add_point);
ClassDB::bind_method(D_METHOD("remove_point", "offset"), &Gradient::remove_point);
@@ -72,8 +71,8 @@ void Gradient::_bind_methods() {
ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &Gradient::set_colors);
ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &Gradient::get_colors);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS);
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS);
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS);
}
Vector<float> Gradient::get_offsets() const {
@@ -104,8 +103,9 @@ void Gradient::set_offsets(const Vector<float> &p_offsets) {
}
void Gradient::set_colors(const Vector<Color> &p_colors) {
- if (points.size() < p_colors.size())
+ if (points.size() < p_colors.size()) {
is_sorted = false;
+ }
points.resize(p_colors.size());
for (int i = 0; i < points.size(); i++) {
points.write[i].color = p_colors[i];
@@ -118,7 +118,6 @@ Vector<Gradient::Point> &Gradient::get_points() {
}
void Gradient::add_point(float p_offset, const Color &p_color) {
-
Point p;
p.offset = p_offset;
p.color = p_color;
@@ -129,7 +128,6 @@ void Gradient::add_point(float p_offset, const Color &p_color) {
}
void Gradient::remove_point(int p_index) {
-
ERR_FAIL_INDEX(p_index, points.size());
ERR_FAIL_COND(points.size() <= 1);
points.remove(p_index);
@@ -143,32 +141,29 @@ void Gradient::set_points(Vector<Gradient::Point> &p_points) {
}
void Gradient::set_offset(int pos, const float offset) {
-
- ERR_FAIL_COND(pos < 0);
- if (points.size() <= pos)
- points.resize(pos + 1);
+ ERR_FAIL_INDEX(pos, points.size());
+ _update_sorting();
points.write[pos].offset = offset;
is_sorted = false;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Gradient::get_offset(int pos) const {
+float Gradient::get_offset(int pos) {
ERR_FAIL_INDEX_V(pos, points.size(), 0.0);
+ _update_sorting();
return points[pos].offset;
}
void Gradient::set_color(int pos, const Color &color) {
- ERR_FAIL_COND(pos < 0);
- if (points.size() <= pos) {
- points.resize(pos + 1);
- is_sorted = false;
- }
+ ERR_FAIL_INDEX(pos, points.size());
+ _update_sorting();
points.write[pos].color = color;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Color Gradient::get_color(int pos) const {
+Color Gradient::get_color(int pos) {
ERR_FAIL_INDEX_V(pos, points.size(), Color());
+ _update_sorting();
return points[pos].color;
}
diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h
index 2d98f799e2..6518b13ee8 100644
--- a/scene/resources/gradient.h
+++ b/scene/resources/gradient.h
@@ -39,7 +39,6 @@ class Gradient : public Resource {
public:
struct Point {
-
float offset;
Color color;
bool operator<(const Point &p_ponit) const {
@@ -50,6 +49,12 @@ public:
private:
Vector<Point> points;
bool is_sorted;
+ _FORCE_INLINE_ void _update_sorting() {
+ if (!is_sorted) {
+ points.sort();
+ is_sorted = true;
+ }
+ }
protected:
static void _bind_methods();
@@ -65,10 +70,10 @@ public:
Vector<Point> &get_points();
void set_offset(int pos, const float offset);
- float get_offset(int pos) const;
+ float get_offset(int pos);
void set_color(int pos, const Color &color);
- Color get_color(int pos) const;
+ Color get_color(int pos);
void set_offsets(const Vector<float> &p_offsets);
Vector<float> get_offsets() const;
@@ -77,23 +82,21 @@ public:
Vector<Color> get_colors() const;
_FORCE_INLINE_ Color get_color_at_offset(float p_offset) {
-
- if (points.empty())
+ if (points.empty()) {
return Color(0, 0, 0, 1);
-
- if (!is_sorted) {
- points.sort();
- is_sorted = true;
}
+ _update_sorting();
+
//binary search
int low = 0;
int high = points.size() - 1;
int middle = 0;
#ifdef DEBUG_ENABLED
- if (low > high)
+ if (low > high) {
ERR_PRINT("low > high, this may be a bug");
+ }
#endif
while (low <= high) {
@@ -114,13 +117,15 @@ public:
}
int first = middle;
int second = middle + 1;
- if (second >= points.size())
+ if (second >= points.size()) {
return points[points.size() - 1].color;
- if (first < 0)
+ }
+ if (first < 0) {
return points[0].color;
+ }
const Point &pointFirst = points[first];
const Point &pointSecond = points[second];
- return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
+ return pointFirst.color.lerp(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
}
int get_points_count() const;
diff --git a/scene/resources/height_map_shape.cpp b/scene/resources/height_map_shape_3d.cpp
index 2b86d658d8..2ae47bcf3c 100644
--- a/scene/resources/height_map_shape.cpp
+++ b/scene/resources/height_map_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* height_map_shape.cpp */
+/* height_map_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,21 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "height_map_shape.h"
-#include "servers/physics_server.h"
+#include "height_map_shape_3d.h"
+#include "servers/physics_server_3d.h"
-Vector<Vector3> HeightMapShape::get_debug_mesh_lines() {
+Vector<Vector3> HeightMapShape3D::get_debug_mesh_lines() const {
Vector<Vector3> points;
if ((map_width != 0) && (map_depth != 0)) {
-
// This will be slow for large maps...
// also we'll have to figure out how well bullet centers this shape...
Vector2 size(map_width - 1, map_depth - 1);
Vector2 start = size * -0.5;
- PoolRealArray::Read r = map_data.read();
+ const real_t *r = map_data.ptr();
// reserve some memory for our points..
points.resize(((map_width - 1) * map_depth * 2) + (map_width * (map_depth - 1) * 2));
@@ -76,19 +75,22 @@ Vector<Vector3> HeightMapShape::get_debug_mesh_lines() {
return points;
}
-void HeightMapShape::_update_shape() {
+real_t HeightMapShape3D::get_enclosing_radius() const {
+ return Vector3(real_t(map_width), max_height - min_height, real_t(map_depth)).length();
+}
+void HeightMapShape3D::_update_shape() {
Dictionary d;
d["width"] = map_width;
d["depth"] = map_depth;
d["heights"] = map_data;
d["min_height"] = min_height;
d["max_height"] = max_height;
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), d);
- Shape::_update_shape();
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);
+ Shape3D::_update_shape();
}
-void HeightMapShape::set_map_width(int p_new) {
+void HeightMapShape3D::set_map_width(int p_new) {
if (p_new < 1) {
// ignore
} else if (map_width != p_new) {
@@ -98,7 +100,7 @@ void HeightMapShape::set_map_width(int p_new) {
int new_size = map_width * map_depth;
map_data.resize(map_width * map_depth);
- PoolRealArray::Write w = map_data.write();
+ real_t *w = map_data.ptrw();
while (was_size < new_size) {
w[was_size++] = 0.0;
}
@@ -110,11 +112,11 @@ void HeightMapShape::set_map_width(int p_new) {
}
}
-int HeightMapShape::get_map_width() const {
+int HeightMapShape3D::get_map_width() const {
return map_width;
}
-void HeightMapShape::set_map_depth(int p_new) {
+void HeightMapShape3D::set_map_depth(int p_new) {
if (p_new < 1) {
// ignore
} else if (map_depth != p_new) {
@@ -124,7 +126,7 @@ void HeightMapShape::set_map_depth(int p_new) {
int new_size = map_width * map_depth;
map_data.resize(new_size);
- PoolRealArray::Write w = map_data.write();
+ real_t *w = map_data.ptrw();
while (was_size < new_size) {
w[was_size++] = 0.0;
}
@@ -136,11 +138,11 @@ void HeightMapShape::set_map_depth(int p_new) {
}
}
-int HeightMapShape::get_map_depth() const {
+int HeightMapShape3D::get_map_depth() const {
return map_depth;
}
-void HeightMapShape::set_map_data(PoolRealArray p_new) {
+void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) {
int size = (map_width * map_depth);
if (p_new.size() != size) {
// fail
@@ -148,8 +150,8 @@ void HeightMapShape::set_map_data(PoolRealArray p_new) {
}
// copy
- PoolRealArray::Write w = map_data.write();
- PoolRealArray::Read r = p_new.read();
+ real_t *w = map_data.ptrw();
+ const real_t *r = p_new.ptr();
for (int i = 0; i < size; i++) {
float val = r[i];
w[i] = val;
@@ -157,11 +159,13 @@ void HeightMapShape::set_map_data(PoolRealArray p_new) {
min_height = val;
max_height = val;
} else {
- if (min_height > val)
+ if (min_height > val) {
min_height = val;
+ }
- if (max_height < val)
+ if (max_height < val) {
max_height = val;
+ }
}
}
@@ -170,30 +174,29 @@ void HeightMapShape::set_map_data(PoolRealArray p_new) {
_change_notify("map_data");
}
-PoolRealArray HeightMapShape::get_map_data() const {
+PackedFloat32Array HeightMapShape3D::get_map_data() const {
return map_data;
}
-void HeightMapShape::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_map_width", "width"), &HeightMapShape::set_map_width);
- ClassDB::bind_method(D_METHOD("get_map_width"), &HeightMapShape::get_map_width);
- ClassDB::bind_method(D_METHOD("set_map_depth", "height"), &HeightMapShape::set_map_depth);
- ClassDB::bind_method(D_METHOD("get_map_depth"), &HeightMapShape::get_map_depth);
- ClassDB::bind_method(D_METHOD("set_map_data", "data"), &HeightMapShape::set_map_data);
- ClassDB::bind_method(D_METHOD("get_map_data"), &HeightMapShape::get_map_data);
+void HeightMapShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_map_width", "width"), &HeightMapShape3D::set_map_width);
+ ClassDB::bind_method(D_METHOD("get_map_width"), &HeightMapShape3D::get_map_width);
+ ClassDB::bind_method(D_METHOD("set_map_depth", "height"), &HeightMapShape3D::set_map_depth);
+ ClassDB::bind_method(D_METHOD("get_map_depth"), &HeightMapShape3D::get_map_depth);
+ ClassDB::bind_method(D_METHOD("set_map_data", "data"), &HeightMapShape3D::set_map_data);
+ ClassDB::bind_method(D_METHOD("get_map_data"), &HeightMapShape3D::get_map_data);
ADD_PROPERTY(PropertyInfo(Variant::INT, "map_width", PROPERTY_HINT_RANGE, "1,4096,1"), "set_map_width", "get_map_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "map_depth", PROPERTY_HINT_RANGE, "1,4096,1"), "set_map_depth", "get_map_depth");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "map_data"), "set_map_data", "get_map_data");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "map_data"), "set_map_data", "get_map_data");
}
-HeightMapShape::HeightMapShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_HEIGHTMAP)) {
-
+HeightMapShape3D::HeightMapShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_HEIGHTMAP)) {
map_width = 2;
map_depth = 2;
map_data.resize(map_width * map_depth);
- PoolRealArray::Write w = map_data.write();
+ real_t *w = map_data.ptrw();
w[0] = 0.0;
w[1] = 0.0;
w[2] = 0.0;
diff --git a/scene/resources/height_map_shape.h b/scene/resources/height_map_shape_3d.h
index 3a976e3add..9ee8b49689 100644
--- a/scene/resources/height_map_shape.h
+++ b/scene/resources/height_map_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* height_map_shape.h */
+/* height_map_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,32 +31,33 @@
#ifndef HEIGHT_MAP_SHAPE_H
#define HEIGHT_MAP_SHAPE_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class HeightMapShape : public Shape {
- GDCLASS(HeightMapShape, Shape);
+class HeightMapShape3D : public Shape3D {
+ GDCLASS(HeightMapShape3D, Shape3D);
int map_width;
int map_depth;
- PoolRealArray map_data;
+ PackedFloat32Array map_data;
float min_height;
float max_height;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
void set_map_width(int p_new);
int get_map_width() const;
void set_map_depth(int p_new);
int get_map_depth() const;
- void set_map_data(PoolRealArray p_new);
- PoolRealArray get_map_data() const;
+ void set_map_data(PackedFloat32Array p_new);
+ PackedFloat32Array get_map_data() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- HeightMapShape();
+ HeightMapShape3D();
};
#endif /* !HEIGHT_MAP_SHAPE_H */
diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp
index 7f39467403..58653c5f4a 100644
--- a/scene/resources/line_shape_2d.cpp
+++ b/scene/resources/line_shape_2d.cpp
@@ -30,65 +30,61 @@
#include "line_shape_2d.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "core/math/geometry_2d.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
bool LineShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- Vector2 point = get_d() * get_normal();
+ Vector2 point = get_distance() * get_normal();
Vector2 l[2][2] = { { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 }, { point, point + get_normal() * 30 } };
for (int i = 0; i < 2; i++) {
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, l[i]);
- if (p_point.distance_to(closest) < p_tolerance)
+ Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, l[i]);
+ if (p_point.distance_to(closest) < p_tolerance) {
return true;
+ }
}
return false;
}
void LineShape2D::_update_shape() {
-
Array arr;
arr.push_back(normal);
- arr.push_back(d);
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), arr);
+ arr.push_back(distance);
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), arr);
emit_changed();
}
void LineShape2D::set_normal(const Vector2 &p_normal) {
-
normal = p_normal;
_update_shape();
}
-void LineShape2D::set_d(real_t p_d) {
-
- d = p_d;
+void LineShape2D::set_distance(real_t p_distance) {
+ distance = p_distance;
_update_shape();
}
Vector2 LineShape2D::get_normal() const {
-
return normal;
}
-real_t LineShape2D::get_d() const {
- return d;
+real_t LineShape2D::get_distance() const {
+ return distance;
}
void LineShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
- Vector2 point = get_d() * get_normal();
+ Vector2 point = get_distance() * get_normal();
Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
- VS::get_singleton()->canvas_item_add_line(p_to_rid, l1[0], l1[1], p_color, 3);
+ RS::get_singleton()->canvas_item_add_line(p_to_rid, l1[0], l1[1], p_color, 3);
Vector2 l2[2] = { point, point + get_normal() * 30 };
- VS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3);
+ RS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3);
}
-Rect2 LineShape2D::get_rect() const {
- Vector2 point = get_d() * get_normal();
+Rect2 LineShape2D::get_rect() const {
+ Vector2 point = get_distance() * get_normal();
Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
Vector2 l2[2] = { point, point + get_normal() * 30 };
@@ -100,22 +96,24 @@ Rect2 LineShape2D::get_rect() const {
return rect;
}
-void LineShape2D::_bind_methods() {
+real_t LineShape2D::get_enclosing_radius() const {
+ return distance;
+}
+void LineShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_normal", "normal"), &LineShape2D::set_normal);
ClassDB::bind_method(D_METHOD("get_normal"), &LineShape2D::get_normal);
- ClassDB::bind_method(D_METHOD("set_d", "d"), &LineShape2D::set_d);
- ClassDB::bind_method(D_METHOD("get_d"), &LineShape2D::get_d);
+ ClassDB::bind_method(D_METHOD("set_distance", "distance"), &LineShape2D::set_distance);
+ ClassDB::bind_method(D_METHOD("get_distance"), &LineShape2D::get_distance);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "set_normal", "get_normal");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "d"), "set_d", "get_d");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance"), "set_distance", "get_distance");
}
LineShape2D::LineShape2D() :
- Shape2D(Physics2DServer::get_singleton()->line_shape_create()) {
-
- normal = Vector2(0, -1);
- d = 0;
+ Shape2D(PhysicsServer2D::get_singleton()->line_shape_create()) {
+ normal = Vector2(0, 1);
+ distance = 0;
_update_shape();
}
diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h
index 7babfe12f6..7e67a8f67c 100644
--- a/scene/resources/line_shape_2d.h
+++ b/scene/resources/line_shape_2d.h
@@ -37,7 +37,7 @@ class LineShape2D : public Shape2D {
GDCLASS(LineShape2D, Shape2D);
Vector2 normal;
- real_t d;
+ real_t distance;
void _update_shape();
@@ -45,16 +45,17 @@ protected:
static void _bind_methods();
public:
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
void set_normal(const Vector2 &p_normal);
- void set_d(real_t p_d);
+ void set_distance(real_t p_distance);
Vector2 get_normal() const;
- real_t get_d() const;
+ real_t get_distance() const;
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
LineShape2D();
};
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index ab4dbb758a..1e95a35726 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -39,52 +39,48 @@
#include "scene/scene_string_names.h"
void Material::set_next_pass(const Ref<Material> &p_pass) {
-
- for (Ref<Material> pass_child = p_pass; pass_child != NULL; pass_child = pass_child->get_next_pass()) {
+ for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) {
ERR_FAIL_COND_MSG(pass_child == this, "Can't set as next_pass one of its parents to prevent crashes due to recursive loop.");
}
- if (next_pass == p_pass)
+ if (next_pass == p_pass) {
return;
+ }
next_pass = p_pass;
RID next_pass_rid;
- if (next_pass.is_valid())
+ if (next_pass.is_valid()) {
next_pass_rid = next_pass->get_rid();
- VS::get_singleton()->material_set_next_pass(material, next_pass_rid);
+ }
+ RS::get_singleton()->material_set_next_pass(material, next_pass_rid);
}
Ref<Material> Material::get_next_pass() const {
-
return next_pass;
}
void Material::set_render_priority(int p_priority) {
-
ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN);
ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX);
render_priority = p_priority;
- VS::get_singleton()->material_set_render_priority(material, p_priority);
+ RS::get_singleton()->material_set_render_priority(material, p_priority);
}
int Material::get_render_priority() const {
-
return render_priority;
}
RID Material::get_rid() const {
-
return material;
}
-void Material::_validate_property(PropertyInfo &property) const {
+void Material::_validate_property(PropertyInfo &property) const {
if (!_can_do_next_pass() && property.name == "next_pass") {
property.usage = 0;
}
}
void Material::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass);
ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass);
@@ -99,22 +95,18 @@ void Material::_bind_methods() {
}
Material::Material() {
-
- material = VisualServer::get_singleton()->material_create();
+ material = RenderingServer::get_singleton()->material_create();
render_priority = 0;
}
Material::~Material() {
-
- VisualServer::get_singleton()->free(material);
+ RenderingServer::get_singleton()->free(material);
}
///////////////////////////////////
bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
-
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (!pr) {
String n = p_name;
@@ -126,7 +118,7 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
}
}
if (pr) {
- VisualServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
return true;
}
}
@@ -135,9 +127,7 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
}
bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
-
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (!pr) {
String n = p_name;
@@ -150,7 +140,7 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
}
if (pr) {
- r_ret = VisualServer::get_singleton()->material_get_param(_get_material(), pr);
+ r_ret = RenderingServer::get_singleton()->material_get_param(_get_material(), pr);
return true;
}
}
@@ -159,19 +149,16 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
}
void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
-
if (!shader.is_null()) {
-
shader->get_param_list(p_list);
}
}
bool ShaderMaterial::property_can_revert(const String &p_name) {
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (pr) {
- Variant default_value = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr);
+ Variant default_value = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr);
Variant current_value;
_get(p_name, current_value);
return default_value.get_type() != Variant::NIL && default_value != current_value;
@@ -185,19 +172,18 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) {
if (shader.is_valid()) {
StringName pr = shader->remap_param(p_name);
if (pr) {
- r_ret = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr);
+ r_ret = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr);
}
}
return r_ret;
}
void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
-
// Only connect/disconnect the signal when running in the editor.
// This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`)
// does nothing in non-editor builds anyway. See GH-34741 for details.
if (shader.is_valid() && Engine::get_singleton()->is_editor_hint()) {
- shader->disconnect("changed", this, "_shader_changed");
+ shader->disconnect("changed", callable_mp(this, &ShaderMaterial::_shader_changed));
}
shader = p_shader;
@@ -207,28 +193,25 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
rid = shader->get_rid();
if (Engine::get_singleton()->is_editor_hint()) {
- shader->connect("changed", this, "_shader_changed");
+ shader->connect("changed", callable_mp(this, &ShaderMaterial::_shader_changed));
}
}
- VS::get_singleton()->material_set_shader(_get_material(), rid);
+ RS::get_singleton()->material_set_shader(_get_material(), rid);
_change_notify(); //properties for shader exposed
emit_changed();
}
Ref<Shader> ShaderMaterial::get_shader() const {
-
return shader;
}
void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
-
- VS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
+ RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
}
Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
-
- return VS::get_singleton()->material_get_param(_get_material(), p_param);
+ return RS::get_singleton()->material_get_param(_get_material(), p_param);
}
void ShaderMaterial::_shader_changed() {
@@ -236,12 +219,10 @@ void ShaderMaterial::_shader_changed() {
}
void ShaderMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader);
ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader);
ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param);
ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &ShaderMaterial::get_shader_param);
- ClassDB::bind_method(D_METHOD("_shader_changed"), &ShaderMaterial::_shader_changed);
ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ShaderMaterial::property_can_revert);
ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ShaderMaterial::property_get_revert);
@@ -249,7 +230,6 @@ void ShaderMaterial::_bind_methods() {
}
void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
#else
@@ -258,7 +238,6 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id
String f = p_function.operator String();
if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) {
-
if (shader.is_valid()) {
List<PropertyInfo> pl;
shader->get_param_list(&pl);
@@ -271,15 +250,15 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id
}
bool ShaderMaterial::_can_do_next_pass() const {
-
return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL;
}
Shader::Mode ShaderMaterial::get_shader_mode() const {
- if (shader.is_valid())
+ if (shader.is_valid()) {
return shader->get_mode();
- else
+ } else {
return Shader::MODE_SPATIAL;
+ }
}
ShaderMaterial::ShaderMaterial() {
@@ -290,18 +269,13 @@ ShaderMaterial::~ShaderMaterial() {
/////////////////////////////////
-Mutex *SpatialMaterial::material_mutex = NULL;
-SelfList<SpatialMaterial>::List *SpatialMaterial::dirty_materials = NULL;
-Map<SpatialMaterial::MaterialKey, SpatialMaterial::ShaderData> SpatialMaterial::shader_map;
-SpatialMaterial::ShaderNames *SpatialMaterial::shader_names = NULL;
-
-void SpatialMaterial::init_shaders() {
+Mutex BaseMaterial3D::material_mutex;
+SelfList<BaseMaterial3D>::List *BaseMaterial3D::dirty_materials = nullptr;
+Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::shader_map;
+BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = nullptr;
-#ifndef NO_THREADS
- material_mutex = Mutex::create();
-#endif
-
- dirty_materials = memnew(SelfList<SpatialMaterial>::List);
+void BaseMaterial3D::init_shaders() {
+ dirty_materials = memnew(SelfList<BaseMaterial3D>::List);
shader_names = memnew(ShaderNames);
@@ -317,9 +291,9 @@ void SpatialMaterial::init_shaders() {
shader_names->clearcoat = "clearcoat";
shader_names->clearcoat_gloss = "clearcoat_gloss";
shader_names->anisotropy = "anisotropy_ratio";
- shader_names->depth_scale = "depth_scale";
+ shader_names->heightmap_scale = "heightmap_scale";
shader_names->subsurface_scattering_strength = "subsurface_scattering_strength";
- shader_names->transmission = "transmission";
+ shader_names->backlight = "backlight";
shader_names->refraction = "refraction";
shader_names->point_size = "point_size";
shader_names->uv1_scale = "uv1_scale";
@@ -332,9 +306,9 @@ void SpatialMaterial::init_shaders() {
shader_names->particles_anim_h_frames = "particles_anim_h_frames";
shader_names->particles_anim_v_frames = "particles_anim_v_frames";
shader_names->particles_anim_loop = "particles_anim_loop";
- shader_names->depth_min_layers = "depth_min_layers";
- shader_names->depth_max_layers = "depth_max_layers";
- shader_names->depth_flip = "depth_flip";
+ shader_names->heightmap_min_layers = "heightmap_min_layers";
+ shader_names->heightmap_max_layers = "heightmap_max_layers";
+ shader_names->heightmap_flip = "heightmap_flip";
shader_names->grow = "grow";
@@ -345,14 +319,18 @@ void SpatialMaterial::init_shaders() {
shader_names->distance_fade_max = "distance_fade_max";
shader_names->metallic_texture_channel = "metallic_texture_channel";
- shader_names->roughness_texture_channel = "roughness_texture_channel";
shader_names->ao_texture_channel = "ao_texture_channel";
shader_names->clearcoat_texture_channel = "clearcoat_texture_channel";
shader_names->rim_texture_channel = "rim_texture_channel";
- shader_names->depth_texture_channel = "depth_texture_channel";
+ shader_names->heightmap_texture_channel = "heightmap_texture_channel";
shader_names->refraction_texture_channel = "refraction_texture_channel";
shader_names->alpha_scissor_threshold = "alpha_scissor_threshold";
+ shader_names->transmittance_color = "transmittance_color";
+ shader_names->transmittance_curve = "transmittance_curve";
+ shader_names->transmittance_depth = "transmittance_depth";
+ shader_names->transmittance_boost = "transmittance_boost";
+
shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo";
shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic";
shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness";
@@ -362,46 +340,43 @@ void SpatialMaterial::init_shaders() {
shader_names->texture_names[TEXTURE_CLEARCOAT] = "texture_clearcoat";
shader_names->texture_names[TEXTURE_FLOWMAP] = "texture_flowmap";
shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion";
- shader_names->texture_names[TEXTURE_DEPTH] = "texture_depth";
+ shader_names->texture_names[TEXTURE_HEIGHTMAP] = "texture_heightmap";
shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering";
- shader_names->texture_names[TEXTURE_TRANSMISSION] = "texture_transmission";
+ shader_names->texture_names[TEXTURE_SUBSURFACE_TRANSMITTANCE] = "texture_subsurface_transmittance";
+ shader_names->texture_names[TEXTURE_BACKLIGHT] = "texture_backlight";
shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction";
shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask";
shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo";
shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal";
+ shader_names->texture_names[TEXTURE_ORM] = "texture_orm";
}
-Ref<SpatialMaterial> SpatialMaterial::materials_for_2d[SpatialMaterial::MAX_MATERIALS_FOR_2D];
-
-void SpatialMaterial::finish_shaders() {
+Ref<StandardMaterial3D> BaseMaterial3D::materials_for_2d[BaseMaterial3D::MAX_MATERIALS_FOR_2D];
+void BaseMaterial3D::finish_shaders() {
for (int i = 0; i < MAX_MATERIALS_FOR_2D; i++) {
materials_for_2d[i].unref();
}
-#ifndef NO_THREADS
- memdelete(material_mutex);
-#endif
-
memdelete(dirty_materials);
- dirty_materials = NULL;
+ dirty_materials = nullptr;
memdelete(shader_names);
}
-void SpatialMaterial::_update_shader() {
-
+void BaseMaterial3D::_update_shader() {
dirty_materials->remove(&element);
MaterialKey mk = _compute_key();
- if (mk.key == current_key.key)
+ if (mk == current_key) {
return; //no update required in the end
+ }
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
if (shader_map[current_key].users == 0) {
//deallocate shader, as it's no longer in use
- VS::get_singleton()->free(shader_map[current_key].shader);
+ RS::get_singleton()->free(shader_map[current_key].shader);
shader_map.erase(current_key);
}
}
@@ -409,20 +384,57 @@ void SpatialMaterial::_update_shader() {
current_key = mk;
if (shader_map.has(mk)) {
-
- VS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
+ RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
shader_map[mk].users++;
return;
}
+ String texfilter_str;
+ switch (texture_filter) {
+ case TEXTURE_FILTER_NEAREST:
+ texfilter_str = "filter_nearest";
+ break;
+ case TEXTURE_FILTER_LINEAR:
+ texfilter_str = "filter_linear";
+ break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
+ texfilter_str = "filter_nearest_mipmap";
+ break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
+ texfilter_str = "filter_linear_mipmap";
+ break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC:
+ texfilter_str = "filter_nearest_mipmap_aniso";
+ break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC:
+ texfilter_str = "filter_linear_mipmap_aniso";
+ break;
+ case TEXTURE_FILTER_MAX:
+ break; // Internal value, skip.
+ }
+
+ if (flags[FLAG_USE_TEXTURE_REPEAT]) {
+ texfilter_str += ",repeat_enable";
+ } else {
+ texfilter_str += ",repeat_disable";
+ }
+
//must create a shader!
String code = "shader_type spatial;\nrender_mode ";
switch (blend_mode) {
- case BLEND_MODE_MIX: code += "blend_mix"; break;
- case BLEND_MODE_ADD: code += "blend_add"; break;
- case BLEND_MODE_SUB: code += "blend_sub"; break;
- case BLEND_MODE_MUL: code += "blend_mul"; break;
+ case BLEND_MODE_MIX:
+ code += "blend_mix";
+ break;
+ case BLEND_MODE_ADD:
+ code += "blend_add";
+ break;
+ case BLEND_MODE_SUB:
+ code += "blend_sub";
+ break;
+ case BLEND_MODE_MUL:
+ code += "blend_mul";
+ break;
}
DepthDrawMode ddm = depth_draw_mode;
@@ -431,62 +443,92 @@ void SpatialMaterial::_update_shader() {
}
switch (ddm) {
- case DEPTH_DRAW_OPAQUE_ONLY: code += ",depth_draw_opaque"; break;
- case DEPTH_DRAW_ALWAYS: code += ",depth_draw_always"; break;
- case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break;
- case DEPTH_DRAW_ALPHA_OPAQUE_PREPASS: code += ",depth_draw_alpha_prepass"; break;
+ case DEPTH_DRAW_OPAQUE_ONLY:
+ code += ",depth_draw_opaque";
+ break;
+ case DEPTH_DRAW_ALWAYS:
+ code += ",depth_draw_always";
+ break;
+ case DEPTH_DRAW_DISABLED:
+ code += ",depth_draw_never";
+ break;
+ }
+
+ if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
+ code += ",depth_prepass_alpha";
}
switch (cull_mode) {
- case CULL_BACK: code += ",cull_back"; break;
- case CULL_FRONT: code += ",cull_front"; break;
- case CULL_DISABLED: code += ",cull_disabled"; break;
+ case CULL_BACK:
+ code += ",cull_back";
+ break;
+ case CULL_FRONT:
+ code += ",cull_front";
+ break;
+ case CULL_DISABLED:
+ code += ",cull_disabled";
+ break;
}
switch (diffuse_mode) {
- case DIFFUSE_BURLEY: code += ",diffuse_burley"; break;
- case DIFFUSE_LAMBERT: code += ",diffuse_lambert"; break;
- case DIFFUSE_LAMBERT_WRAP: code += ",diffuse_lambert_wrap"; break;
- case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break;
- case DIFFUSE_TOON: code += ",diffuse_toon"; break;
+ case DIFFUSE_BURLEY:
+ code += ",diffuse_burley";
+ break;
+ case DIFFUSE_LAMBERT:
+ code += ",diffuse_lambert";
+ break;
+ case DIFFUSE_LAMBERT_WRAP:
+ code += ",diffuse_lambert_wrap";
+ break;
+ case DIFFUSE_OREN_NAYAR:
+ code += ",diffuse_oren_nayar";
+ break;
+ case DIFFUSE_TOON:
+ code += ",diffuse_toon";
+ break;
}
switch (specular_mode) {
- case SPECULAR_SCHLICK_GGX: code += ",specular_schlick_ggx"; break;
- case SPECULAR_BLINN: code += ",specular_blinn"; break;
- case SPECULAR_PHONG: code += ",specular_phong"; break;
- case SPECULAR_TOON: code += ",specular_toon"; break;
- case SPECULAR_DISABLED: code += ",specular_disabled"; break;
- }
-
- if (flags[FLAG_UNSHADED]) {
+ case SPECULAR_SCHLICK_GGX:
+ code += ",specular_schlick_ggx";
+ break;
+ case SPECULAR_BLINN:
+ code += ",specular_blinn";
+ break;
+ case SPECULAR_PHONG:
+ code += ",specular_phong";
+ break;
+ case SPECULAR_TOON:
+ code += ",specular_toon";
+ break;
+ case SPECULAR_DISABLED:
+ code += ",specular_disabled";
+ break;
+ }
+ if (features[FEATURE_SUBSURFACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) {
+ code += ",sss_mode_skin";
+ }
+
+ if (shading_mode == SHADING_MODE_UNSHADED) {
code += ",unshaded";
}
if (flags[FLAG_DISABLE_DEPTH_TEST]) {
- code += ",depth_test_disable";
+ code += ",depth_test_disabled";
}
- if (flags[FLAG_USE_VERTEX_LIGHTING]) {
+ if (shading_mode == SHADING_MODE_PER_VERTEX) {
code += ",vertex_lighting";
}
- if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) {
- code += ",world_vertex_coords";
- }
if (flags[FLAG_DONT_RECEIVE_SHADOWS]) {
code += ",shadows_disabled";
}
if (flags[FLAG_DISABLE_AMBIENT_LIGHT]) {
code += ",ambient_light_disabled";
}
- if (flags[FLAG_ENSURE_CORRECT_NORMALS]) {
- code += ",ensure_correct_normals";
- }
if (flags[FLAG_USE_SHADOW_TO_OPACITY]) {
code += ",shadow_to_opacity";
}
code += ";\n";
code += "uniform vec4 albedo : hint_color;\n";
- code += "uniform sampler2D texture_albedo : hint_albedo;\n";
- code += "uniform float specular;\n";
- code += "uniform float metallic;\n";
+ code += "uniform sampler2D texture_albedo : hint_albedo," + texfilter_str + ";\n";
if (grow_enabled) {
code += "uniform float grow;\n";
}
@@ -499,21 +541,41 @@ void SpatialMaterial::_update_shader() {
code += "uniform float distance_fade_max;\n";
}
- if (flags[FLAG_USE_ALPHA_SCISSOR]) {
+ if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
code += "uniform float alpha_scissor_threshold;\n";
}
- code += "uniform float roughness : hint_range(0,1);\n";
+
code += "uniform float point_size : hint_range(0,128);\n";
- if (textures[TEXTURE_METALLIC] != NULL) {
- code += "uniform sampler2D texture_metallic : hint_white;\n";
+ //TODO ALL HINTS
+ if (!orm) {
+ code += "uniform float roughness : hint_range(0,1);\n";
+ code += "uniform sampler2D texture_metallic : hint_white," + texfilter_str + ";\n";
code += "uniform vec4 metallic_texture_channel;\n";
- }
+ switch (roughness_texture_channel) {
+ case TEXTURE_CHANNEL_RED: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_r," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_GREEN: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_g," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_BLUE: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_b," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_ALPHA: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_a," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_GRAYSCALE: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_gray," + texfilter_str + ";\n";
+ } break;
+ }
- if (textures[TEXTURE_ROUGHNESS] != NULL) {
- code += "uniform sampler2D texture_roughness : hint_white;\n";
- code += "uniform vec4 roughness_texture_channel;\n";
+ code += "uniform float specular;\n";
+ code += "uniform float metallic;\n";
+ } else {
+ code += "uniform sampler2D texture_orm : hint_roughness_g," + texfilter_str + ";\n";
}
+
if (billboard_mode == BILLBOARD_PARTICLES) {
code += "uniform int particles_anim_h_frames;\n";
code += "uniform int particles_anim_v_frames;\n";
@@ -521,35 +583,34 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_EMISSION]) {
-
- code += "uniform sampler2D texture_emission : hint_black_albedo;\n";
+ code += "uniform sampler2D texture_emission : hint_black_albedo," + texfilter_str + ";\n";
code += "uniform vec4 emission : hint_color;\n";
code += "uniform float emission_energy;\n";
}
if (features[FEATURE_REFRACTION]) {
- code += "uniform sampler2D texture_refraction;\n";
+ code += "uniform sampler2D texture_refraction : " + texfilter_str + ";\n";
code += "uniform float refraction : hint_range(-16,16);\n";
code += "uniform vec4 refraction_texture_channel;\n";
}
if (features[FEATURE_NORMAL_MAPPING]) {
- code += "uniform sampler2D texture_normal : hint_normal;\n";
+ code += "uniform sampler2D texture_normal : hint_roughness_normal," + texfilter_str + ";\n";
code += "uniform float normal_scale : hint_range(-16,16);\n";
}
if (features[FEATURE_RIM]) {
code += "uniform float rim : hint_range(0,1);\n";
code += "uniform float rim_tint : hint_range(0,1);\n";
- code += "uniform sampler2D texture_rim : hint_white;\n";
+ code += "uniform sampler2D texture_rim : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_CLEARCOAT]) {
code += "uniform float clearcoat : hint_range(0,1);\n";
code += "uniform float clearcoat_gloss : hint_range(0,1);\n";
- code += "uniform sampler2D texture_clearcoat : hint_white;\n";
+ code += "uniform sampler2D texture_clearcoat : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_ANISOTROPY]) {
code += "uniform float anisotropy_ratio : hint_range(0,256);\n";
- code += "uniform sampler2D texture_flowmap : hint_aniso;\n";
+ code += "uniform sampler2D texture_flowmap : hint_aniso," + texfilter_str + ";\n";
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
code += "uniform sampler2D texture_ambient_occlusion : hint_white;\n";
@@ -558,29 +619,35 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_DETAIL]) {
- code += "uniform sampler2D texture_detail_albedo : hint_albedo;\n";
- code += "uniform sampler2D texture_detail_normal : hint_normal;\n";
- code += "uniform sampler2D texture_detail_mask : hint_white;\n";
+ code += "uniform sampler2D texture_detail_albedo : hint_albedo," + texfilter_str + ";\n";
+ code += "uniform sampler2D texture_detail_normal : hint_normal," + texfilter_str + ";\n";
+ code += "uniform sampler2D texture_detail_mask : hint_white," + texfilter_str + ";\n";
}
- if (features[FEATURE_SUBSURACE_SCATTERING]) {
-
+ if (features[FEATURE_SUBSURFACE_SCATTERING]) {
code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n";
- code += "uniform sampler2D texture_subsurface_scattering : hint_white;\n";
+ code += "uniform sampler2D texture_subsurface_scattering : hint_white," + texfilter_str + ";\n";
}
- if (features[FEATURE_TRANSMISSION]) {
+ if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
+ code += "uniform vec4 transmittance_color : hint_color;\n";
+ code += "uniform float transmittance_depth;\n";
+ code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n";
+ code += "uniform float transmittance_curve;\n";
+ code += "uniform float transmittance_boost;\n";
+ }
- code += "uniform vec4 transmission : hint_color;\n";
- code += "uniform sampler2D texture_transmission : hint_black;\n";
+ if (features[FEATURE_BACKLIGHT]) {
+ code += "uniform vec4 backlight : hint_color;\n";
+ code += "uniform sampler2D texture_backlight : hint_black," + texfilter_str + ";\n";
}
- if (features[FEATURE_DEPTH_MAPPING]) {
- code += "uniform sampler2D texture_depth : hint_black;\n";
- code += "uniform float depth_scale;\n";
- code += "uniform int depth_min_layers;\n";
- code += "uniform int depth_max_layers;\n";
- code += "uniform vec2 depth_flip;\n";
+ if (features[FEATURE_HEIGHT_MAPPING]) {
+ code += "uniform sampler2D texture_heightmap : hint_black," + texfilter_str + ";\n";
+ code += "uniform float heightmap_scale;\n";
+ code += "uniform int heightmap_min_layers;\n";
+ code += "uniform int heightmap_max_layers;\n";
+ code += "uniform vec2 heightmap_flip;\n";
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "varying vec3 uv1_triplanar_pos;\n";
@@ -608,18 +675,15 @@ void SpatialMaterial::_update_shader() {
code += "void vertex() {\n";
if (flags[FLAG_SRGB_VERTEX_COLOR]) {
-
code += "\tif (!OUTPUT_IS_SRGB) {\n";
code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n";
code += "\t}\n";
}
if (flags[FLAG_USE_POINT_SIZE]) {
-
code += "\tPOINT_SIZE=point_size;\n";
}
- if (flags[FLAG_USE_VERTEX_LIGHTING]) {
-
+ if (shading_mode == SHADING_MODE_PER_VERTEX) {
code += "\tROUGHNESS=roughness;\n";
}
@@ -629,10 +693,8 @@ void SpatialMaterial::_update_shader() {
switch (billboard_mode) {
case BILLBOARD_DISABLED: {
-
} break;
case BILLBOARD_ENABLED: {
-
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n";
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
@@ -640,7 +702,6 @@ void SpatialMaterial::_update_shader() {
}
} break;
case BILLBOARD_FIXED_Y: {
-
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n";
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
@@ -650,7 +711,6 @@ void SpatialMaterial::_update_shader() {
}
} break;
case BILLBOARD_PARTICLES: {
-
//make billboard
code += "\tmat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n";
//rotate by rotation
@@ -674,7 +734,6 @@ void SpatialMaterial::_update_shader() {
}
if (flags[FLAG_FIXED_SIZE]) {
-
code += "\tif (PROJECTION_MATRIX[3][3] != 0.0) {\n";
//orthogonal matrix, try to do about the same
//with viewport size
@@ -709,7 +768,6 @@ void SpatialMaterial::_update_shader() {
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
-
code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
@@ -717,7 +775,6 @@ void SpatialMaterial::_update_shader() {
}
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
-
code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
@@ -750,33 +807,49 @@ void SpatialMaterial::_update_shader() {
code += "\tvec2 base_uv2 = UV2;\n";
}
- if (!VisualServer::get_singleton()->is_low_end() && features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar
+ if (!RenderingServer::get_singleton()->is_low_end() && features[FEATURE_HEIGHT_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //heightmap not supported with triplanar
code += "\t{\n";
- code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-)
+ code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*heightmap_flip.x,-BINORMAL*heightmap_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-)
if (deep_parallax) {
- code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
+ code += "\t\tfloat num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
code += "\t\tfloat layer_depth = 1.0 / num_layers;\n";
code += "\t\tfloat current_layer_depth = 0.0;\n";
- code += "\t\tvec2 P = view_dir.xy * depth_scale;\n";
+ code += "\t\tvec2 P = view_dir.xy * heightmap_scale;\n";
code += "\t\tvec2 delta = P / num_layers;\n";
code += "\t\tvec2 ofs = base_uv;\n";
- code += "\t\tfloat depth = textureLod(texture_depth, ofs,0.0).r;\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\tfloat depth = texture(texture_heightmap, ofs).r;\n";
+ } else {
+ code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, ofs).r;\n";
+ }
code += "\t\tfloat current_depth = 0.0;\n";
code += "\t\twhile(current_depth < depth) {\n";
code += "\t\t\tofs -= delta;\n";
- code += "\t\t\tdepth = textureLod(texture_depth, ofs,0.0).r;\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\t\tdepth = texture(texture_heightmap, ofs).r;\n";
+ } else {
+ code += "\t\t\tdepth = 1.0 - texture(texture_heightmap, ofs).r;\n";
+ }
code += "\t\t\tcurrent_depth += layer_depth;\n";
code += "\t\t}\n";
code += "\t\tvec2 prev_ofs = ofs + delta;\n";
code += "\t\tfloat after_depth = depth - current_depth;\n";
- code += "\t\tfloat before_depth = textureLod(texture_depth, prev_ofs, 0.0).r - current_depth + layer_depth;\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\tfloat before_depth = texture(texture_heightmap, prev_ofs).r - current_depth + layer_depth;\n";
+ } else {
+ code += "\t\tfloat before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;\n";
+ }
code += "\t\tfloat weight = after_depth / (after_depth - before_depth);\n";
code += "\t\tofs = mix(ofs,prev_ofs,weight);\n";
} else {
- code += "\t\tfloat depth = texture(texture_depth, base_uv).r;\n";
- code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * depth_scale);\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\tfloat depth = texture(texture_heightmap, base_uv).r;\n";
+ } else {
+ code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, base_uv).r;\n";
+ }
+ code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * heightmap_scale);\n";
}
code += "\t\tbase_uv=ofs;\n";
@@ -806,29 +879,49 @@ void SpatialMaterial::_update_shader() {
}
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
- if (textures[TEXTURE_METALLIC] != NULL) {
+ if (!orm) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n";
} else {
code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
}
code += "\tMETALLIC = metallic_tex * metallic;\n";
- } else {
- code += "\tMETALLIC = metallic;\n";
- }
- if (textures[TEXTURE_ROUGHNESS] != NULL) {
+ switch (roughness_texture_channel) {
+ case TEXTURE_CHANNEL_RED: {
+ code += "\tvec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_GREEN: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.0,1.0,0.0,0.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_BLUE: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,1.0,0.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_ALPHA: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,0.0,1.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_GRAYSCALE: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n";
+ } break;
+ }
+
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n";
} else {
code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
}
code += "\tROUGHNESS = roughness_tex * roughness;\n";
+ code += "\tSPECULAR = specular;\n";
} else {
- code += "\tROUGHNESS = roughness;\n";
- }
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tfloat orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
+ } else {
+ code += "\tfloat orm_tex = texture(texture_orm,base_uv);\n";
+ }
- code += "\tSPECULAR = specular;\n";
+ code += "\tROUGHNESS = orm_tex.g;\n";
+ code += "\tMETALLIC = orm_tex.b;\n";
+ }
if (features[FEATURE_NORMAL_MAPPING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
@@ -862,7 +955,6 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_REFRACTION]) {
-
if (features[FEATURE_NORMAL_MAPPING]) {
code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) );\n";
} else {
@@ -878,8 +970,10 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO *= 1.0 - ref_amount;\n";
code += "\tALPHA = 1.0;\n";
- } else if (features[FEATURE_TRANSPARENT] || flags[FLAG_USE_ALPHA_SCISSOR] || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
+ } else if (transparency == TRANSPARENCY_ALPHA || transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
code += "\tALPHA = albedo.a * albedo_tex.a;\n";
+ } else if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
+ code += "\tif (albedo.a * albedo_tex.a < alpha_scissor_threshold) discard;\n";
}
if (proximity_fade_enabled) {
@@ -891,8 +985,7 @@ void SpatialMaterial::_update_shader() {
if (distance_fade != DISTANCE_FADE_DISABLED) {
if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) {
-
- if (!VisualServer::get_singleton()->is_low_end()) {
+ if (!RenderingServer::get_singleton()->is_low_end()) {
code += "\t{\n";
if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) {
code += "\t\tfloat fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n";
@@ -965,25 +1058,28 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
- if (flags[FLAG_AO_ON_UV2]) {
- if (flags[FLAG_UV2_USE_TRIPLANAR]) {
- code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
+ if (!orm) {
+ if (flags[FLAG_AO_ON_UV2]) {
+ if (flags[FLAG_UV2_USE_TRIPLANAR]) {
+ code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
+ } else {
+ code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
+ }
} else {
- code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
+ } else {
+ code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
+ }
}
} else {
- if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
- } else {
- code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
- }
+ code += "\tAO = orm_tex.r;\n";
}
code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n";
}
- if (features[FEATURE_SUBSURACE_SCATTERING]) {
-
+ if (features[FEATURE_SUBSURFACE_SCATTERING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
} else {
@@ -992,17 +1088,29 @@ void SpatialMaterial::_update_shader() {
code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
}
- if (features[FEATURE_TRANSMISSION]) {
+ if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec3 transmission_tex = triplanar_texture(texture_transmission,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
+ code += "\tvec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
- code += "\tvec3 transmission_tex = texture(texture_transmission,base_uv).rgb;\n";
+ code += "\tvec4 trans_color_tex = texture(texture_subsurface_transmittance,base_uv);\n";
}
- code += "\tTRANSMISSION = (transmission.rgb+transmission_tex);\n";
+ code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n";
+
+ code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n";
+ code += "\tSSS_TRANSMITTANCE_CURVE=transmittance_curve;\n";
+ code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n";
}
- if (features[FEATURE_DETAIL]) {
+ if (features[FEATURE_BACKLIGHT]) {
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec3 backlight_tex = triplanar_texture(texture_backlight,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
+ } else {
+ code += "\tvec3 backlight_tex = texture(texture_backlight,base_uv).rgb;\n";
+ }
+ code += "\tBACKLIGHT = (backlight.rgb+backlight_tex);\n";
+ }
+ if (features[FEATURE_DETAIL]) {
bool triplanar = (flags[FLAG_UV1_USE_TRIPLANAR] && detail_uv == DETAIL_UV_1) || (flags[FLAG_UV2_USE_TRIPLANAR] && detail_uv == DETAIL_UV_2);
if (triplanar) {
@@ -1017,7 +1125,6 @@ void SpatialMaterial::_update_shader() {
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
-
code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
@@ -1043,417 +1150,436 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
}
- if (flags[FLAG_USE_ALPHA_SCISSOR]) {
- code += "\tALPHA_SCISSOR=alpha_scissor_threshold;\n";
- }
-
code += "}\n";
ShaderData shader_data;
- shader_data.shader = VS::get_singleton()->shader_create();
+ shader_data.shader = RS::get_singleton()->shader_create();
shader_data.users = 1;
- VS::get_singleton()->shader_set_code(shader_data.shader, code);
+ RS::get_singleton()->shader_set_code(shader_data.shader, code);
shader_map[mk] = shader_data;
- VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
+ RS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
}
-void SpatialMaterial::flush_changes() {
-
- if (material_mutex)
- material_mutex->lock();
+void BaseMaterial3D::flush_changes() {
+ MutexLock lock(material_mutex);
while (dirty_materials->first()) {
-
dirty_materials->first()->self()->_update_shader();
}
-
- if (material_mutex)
- material_mutex->unlock();
}
-void SpatialMaterial::_queue_shader_change() {
-
- if (material_mutex)
- material_mutex->lock();
+void BaseMaterial3D::_queue_shader_change() {
+ MutexLock lock(material_mutex);
if (!element.in_list()) {
dirty_materials->add(&element);
}
-
- if (material_mutex)
- material_mutex->unlock();
}
-bool SpatialMaterial::_is_shader_dirty() const {
-
- bool dirty = false;
-
- if (material_mutex)
- material_mutex->lock();
-
- dirty = element.in_list();
+bool BaseMaterial3D::_is_shader_dirty() const {
+ MutexLock lock(material_mutex);
- if (material_mutex)
- material_mutex->unlock();
-
- return dirty;
+ return element.in_list();
}
-void SpatialMaterial::set_albedo(const Color &p_albedo) {
+void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo);
}
-Color SpatialMaterial::get_albedo() const {
-
+Color BaseMaterial3D::get_albedo() const {
return albedo;
}
-void SpatialMaterial::set_specular(float p_specular) {
-
+void BaseMaterial3D::set_specular(float p_specular) {
specular = p_specular;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
}
-float SpatialMaterial::get_specular() const {
-
+float BaseMaterial3D::get_specular() const {
return specular;
}
-void SpatialMaterial::set_roughness(float p_roughness) {
-
+void BaseMaterial3D::set_roughness(float p_roughness) {
roughness = p_roughness;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness);
}
-float SpatialMaterial::get_roughness() const {
-
+float BaseMaterial3D::get_roughness() const {
return roughness;
}
-void SpatialMaterial::set_metallic(float p_metallic) {
-
+void BaseMaterial3D::set_metallic(float p_metallic) {
metallic = p_metallic;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
}
-float SpatialMaterial::get_metallic() const {
-
+float BaseMaterial3D::get_metallic() const {
return metallic;
}
-void SpatialMaterial::set_emission(const Color &p_emission) {
-
+void BaseMaterial3D::set_emission(const Color &p_emission) {
emission = p_emission;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission);
}
-Color SpatialMaterial::get_emission() const {
+Color BaseMaterial3D::get_emission() const {
return emission;
}
-void SpatialMaterial::set_emission_energy(float p_emission_energy) {
-
+void BaseMaterial3D::set_emission_energy(float p_emission_energy) {
emission_energy = p_emission_energy;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy);
}
-float SpatialMaterial::get_emission_energy() const {
+float BaseMaterial3D::get_emission_energy() const {
return emission_energy;
}
-void SpatialMaterial::set_normal_scale(float p_normal_scale) {
-
+void BaseMaterial3D::set_normal_scale(float p_normal_scale) {
normal_scale = p_normal_scale;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale);
}
-float SpatialMaterial::get_normal_scale() const {
+float BaseMaterial3D::get_normal_scale() const {
return normal_scale;
}
-void SpatialMaterial::set_rim(float p_rim) {
-
+void BaseMaterial3D::set_rim(float p_rim) {
rim = p_rim;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim);
}
-float SpatialMaterial::get_rim() const {
+float BaseMaterial3D::get_rim() const {
return rim;
}
-void SpatialMaterial::set_rim_tint(float p_rim_tint) {
-
+void BaseMaterial3D::set_rim_tint(float p_rim_tint) {
rim_tint = p_rim_tint;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint);
}
-float SpatialMaterial::get_rim_tint() const {
+float BaseMaterial3D::get_rim_tint() const {
return rim_tint;
}
-void SpatialMaterial::set_ao_light_affect(float p_ao_light_affect) {
-
+void BaseMaterial3D::set_ao_light_affect(float p_ao_light_affect) {
ao_light_affect = p_ao_light_affect;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect);
}
-float SpatialMaterial::get_ao_light_affect() const {
+float BaseMaterial3D::get_ao_light_affect() const {
return ao_light_affect;
}
-void SpatialMaterial::set_clearcoat(float p_clearcoat) {
-
+void BaseMaterial3D::set_clearcoat(float p_clearcoat) {
clearcoat = p_clearcoat;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat);
}
-float SpatialMaterial::get_clearcoat() const {
-
+float BaseMaterial3D::get_clearcoat() const {
return clearcoat;
}
-void SpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss) {
-
+void BaseMaterial3D::set_clearcoat_gloss(float p_clearcoat_gloss) {
clearcoat_gloss = p_clearcoat_gloss;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_gloss, p_clearcoat_gloss);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_gloss, p_clearcoat_gloss);
}
-float SpatialMaterial::get_clearcoat_gloss() const {
-
+float BaseMaterial3D::get_clearcoat_gloss() const {
return clearcoat_gloss;
}
-void SpatialMaterial::set_anisotropy(float p_anisotropy) {
-
+void BaseMaterial3D::set_anisotropy(float p_anisotropy) {
anisotropy = p_anisotropy;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy);
}
-float SpatialMaterial::get_anisotropy() const {
+float BaseMaterial3D::get_anisotropy() const {
return anisotropy;
}
-void SpatialMaterial::set_depth_scale(float p_depth_scale) {
+void BaseMaterial3D::set_heightmap_scale(float p_heightmap_scale) {
+ heightmap_scale = p_heightmap_scale;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_scale, p_heightmap_scale);
+}
+
+float BaseMaterial3D::get_heightmap_scale() const {
+ return heightmap_scale;
+}
- depth_scale = p_depth_scale;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_scale, p_depth_scale);
+void BaseMaterial3D::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
+ subsurface_scattering_strength = p_subsurface_scattering_strength;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength);
}
-float SpatialMaterial::get_depth_scale() const {
+float BaseMaterial3D::get_subsurface_scattering_strength() const {
+ return subsurface_scattering_strength;
+}
- return depth_scale;
+void BaseMaterial3D::set_transmittance_color(const Color &p_color) {
+ transmittance_color = p_color;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_color, p_color);
}
-void SpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
+Color BaseMaterial3D::get_transmittance_color() const {
+ return transmittance_color;
+}
- subsurface_scattering_strength = p_subsurface_scattering_strength;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength);
+void BaseMaterial3D::set_transmittance_depth(float p_depth) {
+ transmittance_depth = p_depth;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_depth, p_depth);
}
-float SpatialMaterial::get_subsurface_scattering_strength() const {
+float BaseMaterial3D::get_transmittance_depth() const {
+ return transmittance_depth;
+}
- return subsurface_scattering_strength;
+void BaseMaterial3D::set_transmittance_curve(float p_curve) {
+ transmittance_curve = p_curve;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve);
}
-void SpatialMaterial::set_transmission(const Color &p_transmission) {
+float BaseMaterial3D::get_transmittance_curve() const {
+ return transmittance_curve;
+}
- transmission = p_transmission;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->transmission, transmission);
+void BaseMaterial3D::set_transmittance_boost(float p_boost) {
+ transmittance_boost = p_boost;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
}
-Color SpatialMaterial::get_transmission() const {
+float BaseMaterial3D::get_transmittance_boost() const {
+ return transmittance_boost;
+}
- return transmission;
+void BaseMaterial3D::set_backlight(const Color &p_backlight) {
+ backlight = p_backlight;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->backlight, backlight);
}
-void SpatialMaterial::set_refraction(float p_refraction) {
+Color BaseMaterial3D::get_backlight() const {
+ return backlight;
+}
+void BaseMaterial3D::set_refraction(float p_refraction) {
refraction = p_refraction;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction);
}
-float SpatialMaterial::get_refraction() const {
-
+float BaseMaterial3D::get_refraction() const {
return refraction;
}
-void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
-
- if (detail_uv == p_detail_uv)
+void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) {
+ if (detail_uv == p_detail_uv) {
return;
+ }
detail_uv = p_detail_uv;
_queue_shader_change();
}
-SpatialMaterial::DetailUV SpatialMaterial::get_detail_uv() const {
+BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
return detail_uv;
}
-void SpatialMaterial::set_blend_mode(BlendMode p_mode) {
-
- if (blend_mode == p_mode)
+void BaseMaterial3D::set_blend_mode(BlendMode p_mode) {
+ if (blend_mode == p_mode) {
return;
+ }
blend_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::BlendMode SpatialMaterial::get_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
return blend_mode;
}
-void SpatialMaterial::set_detail_blend_mode(BlendMode p_mode) {
-
+void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) {
detail_blend_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::BlendMode SpatialMaterial::get_detail_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
return detail_blend_mode;
}
-void SpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) {
+void BaseMaterial3D::set_transparency(Transparency p_transparency) {
+ if (transparency == p_transparency) {
+ return;
+ }
+
+ transparency = p_transparency;
+ _queue_shader_change();
+ _change_notify();
+}
+
+BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const {
+ return transparency;
+}
- if (depth_draw_mode == p_mode)
+void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
+ if (shading_mode == p_shading_mode) {
return;
+ }
+
+ shading_mode = p_shading_mode;
+ _queue_shader_change();
+ _change_notify();
+}
+
+BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const {
+ return shading_mode;
+}
+
+void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) {
+ if (depth_draw_mode == p_mode) {
+ return;
+ }
depth_draw_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::DepthDrawMode SpatialMaterial::get_depth_draw_mode() const {
+BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
return depth_draw_mode;
}
-void SpatialMaterial::set_cull_mode(CullMode p_mode) {
-
- if (cull_mode == p_mode)
+void BaseMaterial3D::set_cull_mode(CullMode p_mode) {
+ if (cull_mode == p_mode) {
return;
+ }
cull_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::CullMode SpatialMaterial::get_cull_mode() const {
+BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
return cull_mode;
}
-void SpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) {
-
- if (diffuse_mode == p_mode)
+void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) {
+ if (diffuse_mode == p_mode) {
return;
+ }
diffuse_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::DiffuseMode SpatialMaterial::get_diffuse_mode() const {
+BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
return diffuse_mode;
}
-void SpatialMaterial::set_specular_mode(SpecularMode p_mode) {
-
- if (specular_mode == p_mode)
+void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) {
+ if (specular_mode == p_mode) {
return;
+ }
specular_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::SpecularMode SpatialMaterial::get_specular_mode() const {
+BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
return specular_mode;
}
-void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) {
-
+void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
- if (flags[p_flag] == p_enabled)
+ if (flags[p_flag] == p_enabled) {
return;
+ }
flags[p_flag] = p_enabled;
- if ((p_flag == FLAG_USE_ALPHA_SCISSOR) || (p_flag == FLAG_UNSHADED) || (p_flag == FLAG_USE_SHADOW_TO_OPACITY)) {
+ if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) {
_change_notify();
}
_queue_shader_change();
}
-bool SpatialMaterial::get_flag(Flags p_flag) const {
-
+bool BaseMaterial3D::get_flag(Flags p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags[p_flag];
}
-void SpatialMaterial::set_feature(Feature p_feature, bool p_enabled) {
-
+void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
ERR_FAIL_INDEX(p_feature, FEATURE_MAX);
- if (features[p_feature] == p_enabled)
+ if (features[p_feature] == p_enabled) {
return;
+ }
features[p_feature] = p_enabled;
_change_notify();
_queue_shader_change();
}
-bool SpatialMaterial::get_feature(Feature p_feature) const {
-
+bool BaseMaterial3D::get_feature(Feature p_feature) const {
ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false);
return features[p_feature];
}
-void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) {
-
+void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
- VS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
_change_notify();
_queue_shader_change();
}
-Ref<Texture> SpatialMaterial::get_texture(TextureParam p_param) const {
-
- ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture>());
+Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
+ ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture2D>());
return textures[p_param];
}
-Ref<Texture> SpatialMaterial::get_texture_by_name(StringName p_name) const {
- for (int i = 0; i < (int)SpatialMaterial::TEXTURE_MAX; i++) {
+Ref<Texture2D> BaseMaterial3D::get_texture_by_name(StringName p_name) const {
+ for (int i = 0; i < (int)BaseMaterial3D::TEXTURE_MAX; i++) {
TextureParam param = TextureParam(i);
- if (p_name == shader_names->texture_names[param])
+ if (p_name == shader_names->texture_names[param]) {
return textures[param];
+ }
}
- return Ref<Texture>();
+ return Ref<Texture2D>();
}
-void SpatialMaterial::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const {
+void BaseMaterial3D::set_texture_filter(TextureFilter p_filter) {
+ texture_filter = p_filter;
+ _queue_shader_change();
+}
+
+BaseMaterial3D::TextureFilter BaseMaterial3D::get_texture_filter() const {
+ return texture_filter;
+}
+
+void BaseMaterial3D::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const {
if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) {
property.usage = 0;
}
}
-void SpatialMaterial::_validate_high_end(const String &text, PropertyInfo &property) const {
+void BaseMaterial3D::_validate_high_end(const String &text, PropertyInfo &property) const {
if (property.name.begins_with(text)) {
property.usage |= PROPERTY_USAGE_HIGH_END_GFX;
}
}
-void SpatialMaterial::_validate_property(PropertyInfo &property) const {
+void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
_validate_feature("normal", FEATURE_NORMAL_MAPPING, property);
_validate_feature("emission", FEATURE_EMISSION, property);
_validate_feature("rim", FEATURE_RIM, property);
_validate_feature("clearcoat", FEATURE_CLEARCOAT, property);
_validate_feature("anisotropy", FEATURE_ANISOTROPY, property);
_validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property);
- _validate_feature("depth", FEATURE_DEPTH_MAPPING, property);
- _validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property);
- _validate_feature("transmission", FEATURE_TRANSMISSION, property);
+ _validate_feature("heightmap", FEATURE_HEIGHT_MAPPING, property);
+ _validate_feature("subsurf_scatter", FEATURE_SUBSURFACE_SCATTERING, property);
+ _validate_feature("backlight", FEATURE_BACKLIGHT, property);
_validate_feature("refraction", FEATURE_REFRACTION, property);
_validate_feature("detail", FEATURE_DETAIL, property);
@@ -1461,7 +1587,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
_validate_high_end("subsurf_scatter", property);
_validate_high_end("anisotropy", property);
_validate_high_end("clearcoat", property);
- _validate_high_end("depth", property);
+ _validate_high_end("heightmap", property);
if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
property.usage = 0;
@@ -1479,273 +1605,256 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- if (property.name == "params_alpha_scissor_threshold" && !flags[FLAG_USE_ALPHA_SCISSOR]) {
+ if (property.name == "alpha_scissor_threshold" && transparency != TRANSPARENCY_ALPHA_SCISSOR) {
property.usage = 0;
}
- if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) {
+ if ((property.name == "heightmap_min_layers" || property.name == "heightmap_max_layers") && !deep_parallax) {
property.usage = 0;
}
- if (flags[FLAG_UNSHADED]) {
- if (property.name.begins_with("anisotropy")) {
- property.usage = 0;
- }
+ if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture" || property.name == "subsurf_scatter_transmittance_curve")) {
+ property.usage = 0;
+ }
- if (property.name.begins_with("ao")) {
- property.usage = 0;
+ if (orm) {
+ if (property.name == "shading_mode") {
+ property.hint_string = "Unshaded,PerPixel"; //vertex not supported in ORM mode, since no individual roughness.
}
-
- if (property.name.begins_with("clearcoat")) {
+ if (property.name.begins_with("roughness") || property.name.begins_with("metallic") || property.name.begins_with("ao_texture")) {
property.usage = 0;
}
- if (property.name.begins_with("emission")) {
+ } else {
+ if (property.name == "orm_texture") {
property.usage = 0;
}
+ }
- if (property.name.begins_with("metallic")) {
- property.usage = 0;
+ if (shading_mode != SHADING_MODE_PER_PIXEL) {
+ if (shading_mode != SHADING_MODE_PER_VERTEX) {
+ //these may still work per vertex
+ if (property.name.begins_with("ao")) {
+ property.usage = 0;
+ }
+ if (property.name.begins_with("emission")) {
+ property.usage = 0;
+ }
+
+ if (property.name.begins_with("metallic")) {
+ property.usage = 0;
+ }
+ if (property.name.begins_with("rim")) {
+ property.usage = 0;
+ }
+
+ if (property.name.begins_with("roughness")) {
+ property.usage = 0;
+ }
+
+ if (property.name.begins_with("subsurf_scatter")) {
+ property.usage = 0;
+ }
}
- if (property.name.begins_with("normal")) {
+ //these definitely only need per pixel
+ if (property.name.begins_with("anisotropy")) {
property.usage = 0;
}
- if (property.name.begins_with("rim")) {
+ if (property.name.begins_with("clearcoat")) {
property.usage = 0;
}
- if (property.name.begins_with("roughness")) {
+ if (property.name.begins_with("normal")) {
property.usage = 0;
}
- if (property.name.begins_with("subsurf_scatter")) {
+ if (property.name.begins_with("backlight")) {
property.usage = 0;
}
- if (property.name.begins_with("transmission")) {
+ if (property.name.begins_with("transmittance")) {
property.usage = 0;
}
}
}
-void SpatialMaterial::set_line_width(float p_line_width) {
-
- line_width = p_line_width;
- VS::get_singleton()->material_set_line_width(_get_material(), line_width);
-}
-
-float SpatialMaterial::get_line_width() const {
-
- return line_width;
-}
-
-void SpatialMaterial::set_point_size(float p_point_size) {
-
+void BaseMaterial3D::set_point_size(float p_point_size) {
point_size = p_point_size;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size);
}
-float SpatialMaterial::get_point_size() const {
-
+float BaseMaterial3D::get_point_size() const {
return point_size;
}
-void SpatialMaterial::set_uv1_scale(const Vector3 &p_scale) {
-
+void BaseMaterial3D::set_uv1_scale(const Vector3 &p_scale) {
uv1_scale = p_scale;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
}
-Vector3 SpatialMaterial::get_uv1_scale() const {
-
+Vector3 BaseMaterial3D::get_uv1_scale() const {
return uv1_scale;
}
-void SpatialMaterial::set_uv1_offset(const Vector3 &p_offset) {
-
+void BaseMaterial3D::set_uv1_offset(const Vector3 &p_offset) {
uv1_offset = p_offset;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
}
-Vector3 SpatialMaterial::get_uv1_offset() const {
+Vector3 BaseMaterial3D::get_uv1_offset() const {
return uv1_offset;
}
-void SpatialMaterial::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
-
+void BaseMaterial3D::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
uv1_triplanar_sharpness = p_sharpness;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, p_sharpness);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, p_sharpness);
}
-float SpatialMaterial::get_uv1_triplanar_blend_sharpness() const {
-
+float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const {
return uv1_triplanar_sharpness;
}
-void SpatialMaterial::set_uv2_scale(const Vector3 &p_scale) {
-
+void BaseMaterial3D::set_uv2_scale(const Vector3 &p_scale) {
uv2_scale = p_scale;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
}
-Vector3 SpatialMaterial::get_uv2_scale() const {
-
+Vector3 BaseMaterial3D::get_uv2_scale() const {
return uv2_scale;
}
-void SpatialMaterial::set_uv2_offset(const Vector3 &p_offset) {
-
+void BaseMaterial3D::set_uv2_offset(const Vector3 &p_offset) {
uv2_offset = p_offset;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
}
-Vector3 SpatialMaterial::get_uv2_offset() const {
-
+Vector3 BaseMaterial3D::get_uv2_offset() const {
return uv2_offset;
}
-void SpatialMaterial::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
-
+void BaseMaterial3D::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
uv2_triplanar_sharpness = p_sharpness;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, p_sharpness);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, p_sharpness);
}
-float SpatialMaterial::get_uv2_triplanar_blend_sharpness() const {
-
+float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {
return uv2_triplanar_sharpness;
}
-void SpatialMaterial::set_billboard_mode(BillboardMode p_mode) {
-
+void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) {
billboard_mode = p_mode;
_queue_shader_change();
_change_notify();
}
-SpatialMaterial::BillboardMode SpatialMaterial::get_billboard_mode() const {
-
+BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const {
return billboard_mode;
}
-void SpatialMaterial::set_particles_anim_h_frames(int p_frames) {
-
+void BaseMaterial3D::set_particles_anim_h_frames(int p_frames) {
particles_anim_h_frames = p_frames;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
}
-int SpatialMaterial::get_particles_anim_h_frames() const {
-
+int BaseMaterial3D::get_particles_anim_h_frames() const {
return particles_anim_h_frames;
}
-void SpatialMaterial::set_particles_anim_v_frames(int p_frames) {
+void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) {
particles_anim_v_frames = p_frames;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
}
-int SpatialMaterial::get_particles_anim_v_frames() const {
-
+int BaseMaterial3D::get_particles_anim_v_frames() const {
return particles_anim_v_frames;
}
-void SpatialMaterial::set_particles_anim_loop(bool p_loop) {
-
+void BaseMaterial3D::set_particles_anim_loop(bool p_loop) {
particles_anim_loop = p_loop;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop);
}
-bool SpatialMaterial::get_particles_anim_loop() const {
-
+bool BaseMaterial3D::get_particles_anim_loop() const {
return particles_anim_loop;
}
-void SpatialMaterial::set_depth_deep_parallax(bool p_enable) {
-
+void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) {
deep_parallax = p_enable;
_queue_shader_change();
_change_notify();
}
-bool SpatialMaterial::is_depth_deep_parallax_enabled() const {
-
+bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const {
return deep_parallax;
}
-void SpatialMaterial::set_depth_deep_parallax_min_layers(int p_layer) {
-
+void BaseMaterial3D::set_heightmap_deep_parallax_min_layers(int p_layer) {
deep_parallax_min_layers = p_layer;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_min_layers, p_layer);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_min_layers, p_layer);
}
-int SpatialMaterial::get_depth_deep_parallax_min_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
return deep_parallax_min_layers;
}
-void SpatialMaterial::set_depth_deep_parallax_max_layers(int p_layer) {
-
+void BaseMaterial3D::set_heightmap_deep_parallax_max_layers(int p_layer) {
deep_parallax_max_layers = p_layer;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_max_layers, p_layer);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_max_layers, p_layer);
}
-int SpatialMaterial::get_depth_deep_parallax_max_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
return deep_parallax_max_layers;
}
-void SpatialMaterial::set_depth_deep_parallax_flip_tangent(bool p_flip) {
-
- depth_parallax_flip_tangent = p_flip;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1));
+void BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent(bool p_flip) {
+ heightmap_parallax_flip_tangent = p_flip;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
-bool SpatialMaterial::get_depth_deep_parallax_flip_tangent() const {
-
- return depth_parallax_flip_tangent;
+bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const {
+ return heightmap_parallax_flip_tangent;
}
-void SpatialMaterial::set_depth_deep_parallax_flip_binormal(bool p_flip) {
-
- depth_parallax_flip_binormal = p_flip;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1));
+void BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal(bool p_flip) {
+ heightmap_parallax_flip_binormal = p_flip;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
-bool SpatialMaterial::get_depth_deep_parallax_flip_binormal() const {
-
- return depth_parallax_flip_binormal;
+bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {
+ return heightmap_parallax_flip_binormal;
}
-void SpatialMaterial::set_grow_enabled(bool p_enable) {
+void BaseMaterial3D::set_grow_enabled(bool p_enable) {
grow_enabled = p_enable;
_queue_shader_change();
_change_notify();
}
-bool SpatialMaterial::is_grow_enabled() const {
+bool BaseMaterial3D::is_grow_enabled() const {
return grow_enabled;
}
-void SpatialMaterial::set_alpha_scissor_threshold(float p_threshold) {
+void BaseMaterial3D::set_alpha_scissor_threshold(float p_threshold) {
alpha_scissor_threshold = p_threshold;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold);
}
-float SpatialMaterial::get_alpha_scissor_threshold() const {
-
+float BaseMaterial3D::get_alpha_scissor_threshold() const {
return alpha_scissor_threshold;
}
-void SpatialMaterial::set_grow(float p_grow) {
+void BaseMaterial3D::set_grow(float p_grow) {
grow = p_grow;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow);
}
-float SpatialMaterial::get_grow() const {
-
+float BaseMaterial3D::get_grow() const {
return grow;
}
-static Plane _get_texture_mask(SpatialMaterial::TextureChannel p_channel) {
+static Plane _get_texture_mask(BaseMaterial3D::TextureChannel p_channel) {
static const Plane masks[5] = {
Plane(1, 0, 0, 0),
Plane(0, 1, 0, 0),
@@ -1757,81 +1866,82 @@ static Plane _get_texture_mask(SpatialMaterial::TextureChannel p_channel) {
return masks[p_channel];
}
-void SpatialMaterial::set_metallic_texture_channel(TextureChannel p_channel) {
+void BaseMaterial3D::set_metallic_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
metallic_texture_channel = p_channel;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic_texture_channel, _get_texture_mask(p_channel));
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic_texture_channel, _get_texture_mask(p_channel));
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_metallic_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() const {
return metallic_texture_channel;
}
-void SpatialMaterial::set_roughness_texture_channel(TextureChannel p_channel) {
-
+void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
roughness_texture_channel = p_channel;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness_texture_channel, _get_texture_mask(p_channel));
+ _queue_shader_change();
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_roughness_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() const {
return roughness_texture_channel;
}
-void SpatialMaterial::set_ao_texture_channel(TextureChannel p_channel) {
-
+void BaseMaterial3D::set_ao_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
ao_texture_channel = p_channel;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel));
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel));
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_ao_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const {
return ao_texture_channel;
}
-void SpatialMaterial::set_refraction_texture_channel(TextureChannel p_channel) {
-
+void BaseMaterial3D::set_refraction_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
refraction_texture_channel = p_channel;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_refraction_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() const {
return refraction_texture_channel;
}
-RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) {
-
+RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) {
int version = 0;
- if (p_shaded)
+ if (p_shaded) {
version = 1;
- if (p_transparent)
+ }
+ if (p_transparent) {
version |= 2;
- if (p_cut_alpha)
+ }
+ if (p_cut_alpha) {
version |= 4;
- if (p_opaque_prepass)
+ }
+ if (p_opaque_prepass) {
version |= 8;
- if (p_double_sided)
+ }
+ if (p_double_sided) {
version |= 16;
- if (p_billboard)
+ }
+ if (p_billboard) {
version |= 32;
- if (p_billboard_y)
+ }
+ if (p_billboard_y) {
version |= 64;
+ }
if (materials_for_2d[version].is_valid()) {
return materials_for_2d[version]->get_rid();
}
- Ref<SpatialMaterial> material;
+ Ref<StandardMaterial3D> material;
material.instance();
- material->set_flag(FLAG_UNSHADED, !p_shaded);
- material->set_feature(FEATURE_TRANSPARENT, p_transparent);
+ material->set_shading_mode(p_shaded ? SHADING_MODE_PER_PIXEL : SHADING_MODE_UNSHADED);
+ material->set_transparency(p_transparent ? (p_opaque_prepass ? TRANSPARENCY_ALPHA_DEPTH_PRE_PASS : (p_cut_alpha ? TRANSPARENCY_ALPHA_SCISSOR : TRANSPARENCY_ALPHA)) : TRANSPARENCY_DISABLED);
material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK);
- material->set_depth_draw_mode(p_opaque_prepass ? DEPTH_DRAW_ALPHA_OPAQUE_PREPASS : DEPTH_DRAW_OPAQUE_ONLY);
material->set_flag(FLAG_SRGB_VERTEX_COLOR, true);
material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- material->set_flag(FLAG_USE_ALPHA_SCISSOR, p_cut_alpha);
if (p_billboard || p_billboard_y) {
material->set_flag(FLAG_BILLBOARD_KEEP_SCALE, true);
material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED);
@@ -1842,404 +1952,433 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent,
return materials_for_2d[version]->get_rid();
}
-void SpatialMaterial::set_on_top_of_alpha() {
- set_feature(FEATURE_TRANSPARENT, true);
+void BaseMaterial3D::set_on_top_of_alpha() {
+ set_transparency(TRANSPARENCY_DISABLED);
set_render_priority(RENDER_PRIORITY_MAX);
set_flag(FLAG_DISABLE_DEPTH_TEST, true);
}
-void SpatialMaterial::set_proximity_fade(bool p_enable) {
-
+void BaseMaterial3D::set_proximity_fade(bool p_enable) {
proximity_fade_enabled = p_enable;
_queue_shader_change();
_change_notify();
}
-bool SpatialMaterial::is_proximity_fade_enabled() const {
-
+bool BaseMaterial3D::is_proximity_fade_enabled() const {
return proximity_fade_enabled;
}
-void SpatialMaterial::set_proximity_fade_distance(float p_distance) {
-
+void BaseMaterial3D::set_proximity_fade_distance(float p_distance) {
proximity_fade_distance = p_distance;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance);
}
-float SpatialMaterial::get_proximity_fade_distance() const {
+float BaseMaterial3D::get_proximity_fade_distance() const {
return proximity_fade_distance;
}
-void SpatialMaterial::set_distance_fade(DistanceFadeMode p_mode) {
-
+void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
distance_fade = p_mode;
_queue_shader_change();
_change_notify();
}
-SpatialMaterial::DistanceFadeMode SpatialMaterial::get_distance_fade() const {
+BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
return distance_fade;
}
-void SpatialMaterial::set_distance_fade_max_distance(float p_distance) {
-
+void BaseMaterial3D::set_distance_fade_max_distance(float p_distance) {
distance_fade_max_distance = p_distance;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance);
}
-float SpatialMaterial::get_distance_fade_max_distance() const {
+float BaseMaterial3D::get_distance_fade_max_distance() const {
return distance_fade_max_distance;
}
-void SpatialMaterial::set_distance_fade_min_distance(float p_distance) {
-
+void BaseMaterial3D::set_distance_fade_min_distance(float p_distance) {
distance_fade_min_distance = p_distance;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance);
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance);
}
-float SpatialMaterial::get_distance_fade_min_distance() const {
-
+float BaseMaterial3D::get_distance_fade_min_distance() const {
return distance_fade_min_distance;
}
-void SpatialMaterial::set_emission_operator(EmissionOperator p_op) {
-
- if (emission_op == p_op)
+void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) {
+ if (emission_op == p_op) {
return;
+ }
emission_op = p_op;
_queue_shader_change();
}
-SpatialMaterial::EmissionOperator SpatialMaterial::get_emission_operator() const {
-
+BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
return emission_op;
}
-RID SpatialMaterial::get_shader_rid() const {
-
+RID BaseMaterial3D::get_shader_rid() const {
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader;
}
-Shader::Mode SpatialMaterial::get_shader_mode() const {
-
+Shader::Mode BaseMaterial3D::get_shader_mode() const {
return Shader::MODE_SPATIAL;
}
-void SpatialMaterial::_bind_methods() {
+void BaseMaterial3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &BaseMaterial3D::set_albedo);
+ ClassDB::bind_method(D_METHOD("get_albedo"), &BaseMaterial3D::get_albedo);
+
+ ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &BaseMaterial3D::set_transparency);
+ ClassDB::bind_method(D_METHOD("get_transparency"), &BaseMaterial3D::get_transparency);
+
+ ClassDB::bind_method(D_METHOD("set_shading_mode", "shading_mode"), &BaseMaterial3D::set_shading_mode);
+ ClassDB::bind_method(D_METHOD("get_shading_mode"), &BaseMaterial3D::get_shading_mode);
+
+ ClassDB::bind_method(D_METHOD("set_specular", "specular"), &BaseMaterial3D::set_specular);
+ ClassDB::bind_method(D_METHOD("get_specular"), &BaseMaterial3D::get_specular);
- ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
- ClassDB::bind_method(D_METHOD("get_albedo"), &SpatialMaterial::get_albedo);
+ ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &BaseMaterial3D::set_metallic);
+ ClassDB::bind_method(D_METHOD("get_metallic"), &BaseMaterial3D::get_metallic);
- ClassDB::bind_method(D_METHOD("set_specular", "specular"), &SpatialMaterial::set_specular);
- ClassDB::bind_method(D_METHOD("get_specular"), &SpatialMaterial::get_specular);
+ ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &BaseMaterial3D::set_roughness);
+ ClassDB::bind_method(D_METHOD("get_roughness"), &BaseMaterial3D::get_roughness);
- ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &SpatialMaterial::set_metallic);
- ClassDB::bind_method(D_METHOD("get_metallic"), &SpatialMaterial::get_metallic);
+ ClassDB::bind_method(D_METHOD("set_emission", "emission"), &BaseMaterial3D::set_emission);
+ ClassDB::bind_method(D_METHOD("get_emission"), &BaseMaterial3D::get_emission);
- ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &SpatialMaterial::set_roughness);
- ClassDB::bind_method(D_METHOD("get_roughness"), &SpatialMaterial::get_roughness);
+ ClassDB::bind_method(D_METHOD("set_emission_energy", "emission_energy"), &BaseMaterial3D::set_emission_energy);
+ ClassDB::bind_method(D_METHOD("get_emission_energy"), &BaseMaterial3D::get_emission_energy);
- ClassDB::bind_method(D_METHOD("set_emission", "emission"), &SpatialMaterial::set_emission);
- ClassDB::bind_method(D_METHOD("get_emission"), &SpatialMaterial::get_emission);
+ ClassDB::bind_method(D_METHOD("set_normal_scale", "normal_scale"), &BaseMaterial3D::set_normal_scale);
+ ClassDB::bind_method(D_METHOD("get_normal_scale"), &BaseMaterial3D::get_normal_scale);
- ClassDB::bind_method(D_METHOD("set_emission_energy", "emission_energy"), &SpatialMaterial::set_emission_energy);
- ClassDB::bind_method(D_METHOD("get_emission_energy"), &SpatialMaterial::get_emission_energy);
+ ClassDB::bind_method(D_METHOD("set_rim", "rim"), &BaseMaterial3D::set_rim);
+ ClassDB::bind_method(D_METHOD("get_rim"), &BaseMaterial3D::get_rim);
- ClassDB::bind_method(D_METHOD("set_normal_scale", "normal_scale"), &SpatialMaterial::set_normal_scale);
- ClassDB::bind_method(D_METHOD("get_normal_scale"), &SpatialMaterial::get_normal_scale);
+ ClassDB::bind_method(D_METHOD("set_rim_tint", "rim_tint"), &BaseMaterial3D::set_rim_tint);
+ ClassDB::bind_method(D_METHOD("get_rim_tint"), &BaseMaterial3D::get_rim_tint);
- ClassDB::bind_method(D_METHOD("set_rim", "rim"), &SpatialMaterial::set_rim);
- ClassDB::bind_method(D_METHOD("get_rim"), &SpatialMaterial::get_rim);
+ ClassDB::bind_method(D_METHOD("set_clearcoat", "clearcoat"), &BaseMaterial3D::set_clearcoat);
+ ClassDB::bind_method(D_METHOD("get_clearcoat"), &BaseMaterial3D::get_clearcoat);
- ClassDB::bind_method(D_METHOD("set_rim_tint", "rim_tint"), &SpatialMaterial::set_rim_tint);
- ClassDB::bind_method(D_METHOD("get_rim_tint"), &SpatialMaterial::get_rim_tint);
+ ClassDB::bind_method(D_METHOD("set_clearcoat_gloss", "clearcoat_gloss"), &BaseMaterial3D::set_clearcoat_gloss);
+ ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &BaseMaterial3D::get_clearcoat_gloss);
- ClassDB::bind_method(D_METHOD("set_clearcoat", "clearcoat"), &SpatialMaterial::set_clearcoat);
- ClassDB::bind_method(D_METHOD("get_clearcoat"), &SpatialMaterial::get_clearcoat);
+ ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &BaseMaterial3D::set_anisotropy);
+ ClassDB::bind_method(D_METHOD("get_anisotropy"), &BaseMaterial3D::get_anisotropy);
- ClassDB::bind_method(D_METHOD("set_clearcoat_gloss", "clearcoat_gloss"), &SpatialMaterial::set_clearcoat_gloss);
- ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &SpatialMaterial::get_clearcoat_gloss);
+ ClassDB::bind_method(D_METHOD("set_heightmap_scale", "heightmap_scale"), &BaseMaterial3D::set_heightmap_scale);
+ ClassDB::bind_method(D_METHOD("get_heightmap_scale"), &BaseMaterial3D::get_heightmap_scale);
- ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &SpatialMaterial::set_anisotropy);
- ClassDB::bind_method(D_METHOD("get_anisotropy"), &SpatialMaterial::get_anisotropy);
+ ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &BaseMaterial3D::set_subsurface_scattering_strength);
+ ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &BaseMaterial3D::get_subsurface_scattering_strength);
- ClassDB::bind_method(D_METHOD("set_depth_scale", "depth_scale"), &SpatialMaterial::set_depth_scale);
- ClassDB::bind_method(D_METHOD("get_depth_scale"), &SpatialMaterial::get_depth_scale);
+ ClassDB::bind_method(D_METHOD("set_transmittance_color", "color"), &BaseMaterial3D::set_transmittance_color);
+ ClassDB::bind_method(D_METHOD("get_transmittance_color"), &BaseMaterial3D::get_transmittance_color);
- ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &SpatialMaterial::set_subsurface_scattering_strength);
- ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &SpatialMaterial::get_subsurface_scattering_strength);
+ ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth);
+ ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth);
- ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &SpatialMaterial::set_transmission);
- ClassDB::bind_method(D_METHOD("get_transmission"), &SpatialMaterial::get_transmission);
+ ClassDB::bind_method(D_METHOD("set_transmittance_curve", "curve"), &BaseMaterial3D::set_transmittance_curve);
+ ClassDB::bind_method(D_METHOD("get_transmittance_curve"), &BaseMaterial3D::get_transmittance_curve);
- ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction);
- ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction);
+ ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost);
+ ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost);
- ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &SpatialMaterial::set_line_width);
- ClassDB::bind_method(D_METHOD("get_line_width"), &SpatialMaterial::get_line_width);
+ ClassDB::bind_method(D_METHOD("set_backlight", "backlight"), &BaseMaterial3D::set_backlight);
+ ClassDB::bind_method(D_METHOD("get_backlight"), &BaseMaterial3D::get_backlight);
- ClassDB::bind_method(D_METHOD("set_point_size", "point_size"), &SpatialMaterial::set_point_size);
- ClassDB::bind_method(D_METHOD("get_point_size"), &SpatialMaterial::get_point_size);
+ ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &BaseMaterial3D::set_refraction);
+ ClassDB::bind_method(D_METHOD("get_refraction"), &BaseMaterial3D::get_refraction);
- ClassDB::bind_method(D_METHOD("set_detail_uv", "detail_uv"), &SpatialMaterial::set_detail_uv);
- ClassDB::bind_method(D_METHOD("get_detail_uv"), &SpatialMaterial::get_detail_uv);
+ ClassDB::bind_method(D_METHOD("set_point_size", "point_size"), &BaseMaterial3D::set_point_size);
+ ClassDB::bind_method(D_METHOD("get_point_size"), &BaseMaterial3D::get_point_size);
- ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &SpatialMaterial::set_blend_mode);
- ClassDB::bind_method(D_METHOD("get_blend_mode"), &SpatialMaterial::get_blend_mode);
+ ClassDB::bind_method(D_METHOD("set_detail_uv", "detail_uv"), &BaseMaterial3D::set_detail_uv);
+ ClassDB::bind_method(D_METHOD("get_detail_uv"), &BaseMaterial3D::get_detail_uv);
- ClassDB::bind_method(D_METHOD("set_depth_draw_mode", "depth_draw_mode"), &SpatialMaterial::set_depth_draw_mode);
- ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &SpatialMaterial::get_depth_draw_mode);
+ ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &BaseMaterial3D::set_blend_mode);
+ ClassDB::bind_method(D_METHOD("get_blend_mode"), &BaseMaterial3D::get_blend_mode);
- ClassDB::bind_method(D_METHOD("set_cull_mode", "cull_mode"), &SpatialMaterial::set_cull_mode);
- ClassDB::bind_method(D_METHOD("get_cull_mode"), &SpatialMaterial::get_cull_mode);
+ ClassDB::bind_method(D_METHOD("set_depth_draw_mode", "depth_draw_mode"), &BaseMaterial3D::set_depth_draw_mode);
+ ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &BaseMaterial3D::get_depth_draw_mode);
- ClassDB::bind_method(D_METHOD("set_diffuse_mode", "diffuse_mode"), &SpatialMaterial::set_diffuse_mode);
- ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &SpatialMaterial::get_diffuse_mode);
+ ClassDB::bind_method(D_METHOD("set_cull_mode", "cull_mode"), &BaseMaterial3D::set_cull_mode);
+ ClassDB::bind_method(D_METHOD("get_cull_mode"), &BaseMaterial3D::get_cull_mode);
- ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &SpatialMaterial::set_specular_mode);
- ClassDB::bind_method(D_METHOD("get_specular_mode"), &SpatialMaterial::get_specular_mode);
+ ClassDB::bind_method(D_METHOD("set_diffuse_mode", "diffuse_mode"), &BaseMaterial3D::set_diffuse_mode);
+ ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &BaseMaterial3D::get_diffuse_mode);
- ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &SpatialMaterial::set_flag);
- ClassDB::bind_method(D_METHOD("get_flag", "flag"), &SpatialMaterial::get_flag);
+ ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &BaseMaterial3D::set_specular_mode);
+ ClassDB::bind_method(D_METHOD("get_specular_mode"), &BaseMaterial3D::get_specular_mode);
- ClassDB::bind_method(D_METHOD("set_feature", "feature", "enable"), &SpatialMaterial::set_feature);
- ClassDB::bind_method(D_METHOD("get_feature", "feature"), &SpatialMaterial::get_feature);
+ ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &BaseMaterial3D::set_flag);
+ ClassDB::bind_method(D_METHOD("get_flag", "flag"), &BaseMaterial3D::get_flag);
- ClassDB::bind_method(D_METHOD("set_texture", "param", "texture"), &SpatialMaterial::set_texture);
- ClassDB::bind_method(D_METHOD("get_texture", "param"), &SpatialMaterial::get_texture);
+ ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &BaseMaterial3D::set_texture_filter);
+ ClassDB::bind_method(D_METHOD("get_texture_filter"), &BaseMaterial3D::get_texture_filter);
- ClassDB::bind_method(D_METHOD("set_detail_blend_mode", "detail_blend_mode"), &SpatialMaterial::set_detail_blend_mode);
- ClassDB::bind_method(D_METHOD("get_detail_blend_mode"), &SpatialMaterial::get_detail_blend_mode);
+ ClassDB::bind_method(D_METHOD("set_feature", "feature", "enable"), &BaseMaterial3D::set_feature);
+ ClassDB::bind_method(D_METHOD("get_feature", "feature"), &BaseMaterial3D::get_feature);
- ClassDB::bind_method(D_METHOD("set_uv1_scale", "scale"), &SpatialMaterial::set_uv1_scale);
- ClassDB::bind_method(D_METHOD("get_uv1_scale"), &SpatialMaterial::get_uv1_scale);
+ ClassDB::bind_method(D_METHOD("set_texture", "param", "texture"), &BaseMaterial3D::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture", "param"), &BaseMaterial3D::get_texture);
- ClassDB::bind_method(D_METHOD("set_uv1_offset", "offset"), &SpatialMaterial::set_uv1_offset);
- ClassDB::bind_method(D_METHOD("get_uv1_offset"), &SpatialMaterial::get_uv1_offset);
+ ClassDB::bind_method(D_METHOD("set_detail_blend_mode", "detail_blend_mode"), &BaseMaterial3D::set_detail_blend_mode);
+ ClassDB::bind_method(D_METHOD("get_detail_blend_mode"), &BaseMaterial3D::get_detail_blend_mode);
- ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv1_triplanar_blend_sharpness);
- ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness"), &SpatialMaterial::get_uv1_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("set_uv1_scale", "scale"), &BaseMaterial3D::set_uv1_scale);
+ ClassDB::bind_method(D_METHOD("get_uv1_scale"), &BaseMaterial3D::get_uv1_scale);
- ClassDB::bind_method(D_METHOD("set_uv2_scale", "scale"), &SpatialMaterial::set_uv2_scale);
- ClassDB::bind_method(D_METHOD("get_uv2_scale"), &SpatialMaterial::get_uv2_scale);
+ ClassDB::bind_method(D_METHOD("set_uv1_offset", "offset"), &BaseMaterial3D::set_uv1_offset);
+ ClassDB::bind_method(D_METHOD("get_uv1_offset"), &BaseMaterial3D::get_uv1_offset);
- ClassDB::bind_method(D_METHOD("set_uv2_offset", "offset"), &SpatialMaterial::set_uv2_offset);
- ClassDB::bind_method(D_METHOD("get_uv2_offset"), &SpatialMaterial::get_uv2_offset);
+ ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness", "sharpness"), &BaseMaterial3D::set_uv1_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness"), &BaseMaterial3D::get_uv1_triplanar_blend_sharpness);
- ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv2_triplanar_blend_sharpness);
- ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness"), &SpatialMaterial::get_uv2_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("set_uv2_scale", "scale"), &BaseMaterial3D::set_uv2_scale);
+ ClassDB::bind_method(D_METHOD("get_uv2_scale"), &BaseMaterial3D::get_uv2_scale);
- ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpatialMaterial::set_billboard_mode);
- ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpatialMaterial::get_billboard_mode);
+ ClassDB::bind_method(D_METHOD("set_uv2_offset", "offset"), &BaseMaterial3D::set_uv2_offset);
+ ClassDB::bind_method(D_METHOD("get_uv2_offset"), &BaseMaterial3D::get_uv2_offset);
- ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &SpatialMaterial::set_particles_anim_h_frames);
- ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &SpatialMaterial::get_particles_anim_h_frames);
+ ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness", "sharpness"), &BaseMaterial3D::set_uv2_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness"), &BaseMaterial3D::get_uv2_triplanar_blend_sharpness);
- ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &SpatialMaterial::set_particles_anim_v_frames);
- ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &SpatialMaterial::get_particles_anim_v_frames);
+ ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &BaseMaterial3D::set_billboard_mode);
+ ClassDB::bind_method(D_METHOD("get_billboard_mode"), &BaseMaterial3D::get_billboard_mode);
- ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &SpatialMaterial::set_particles_anim_loop);
- ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &SpatialMaterial::get_particles_anim_loop);
+ ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &BaseMaterial3D::set_particles_anim_h_frames);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &BaseMaterial3D::get_particles_anim_h_frames);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax", "enable"), &SpatialMaterial::set_depth_deep_parallax);
- ClassDB::bind_method(D_METHOD("is_depth_deep_parallax_enabled"), &SpatialMaterial::is_depth_deep_parallax_enabled);
+ ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &BaseMaterial3D::set_particles_anim_v_frames);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &BaseMaterial3D::get_particles_anim_v_frames);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_min_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_min_layers);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_min_layers"), &SpatialMaterial::get_depth_deep_parallax_min_layers);
+ ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &BaseMaterial3D::set_particles_anim_loop);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &BaseMaterial3D::get_particles_anim_loop);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_max_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_max_layers);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_max_layers"), &SpatialMaterial::get_depth_deep_parallax_max_layers);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax", "enable"), &BaseMaterial3D::set_heightmap_deep_parallax);
+ ClassDB::bind_method(D_METHOD("is_heightmap_deep_parallax_enabled"), &BaseMaterial3D::is_heightmap_deep_parallax_enabled);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_tangent", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_tangent);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_tangent"), &SpatialMaterial::get_depth_deep_parallax_flip_tangent);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_min_layers", "layer"), &BaseMaterial3D::set_heightmap_deep_parallax_min_layers);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_min_layers"), &BaseMaterial3D::get_heightmap_deep_parallax_min_layers);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_binormal", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_binormal);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_binormal"), &SpatialMaterial::get_depth_deep_parallax_flip_binormal);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_max_layers", "layer"), &BaseMaterial3D::set_heightmap_deep_parallax_max_layers);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_max_layers"), &BaseMaterial3D::get_heightmap_deep_parallax_max_layers);
- ClassDB::bind_method(D_METHOD("set_grow", "amount"), &SpatialMaterial::set_grow);
- ClassDB::bind_method(D_METHOD("get_grow"), &SpatialMaterial::get_grow);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_tangent", "flip"), &BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_tangent"), &BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent);
- ClassDB::bind_method(D_METHOD("set_emission_operator", "operator"), &SpatialMaterial::set_emission_operator);
- ClassDB::bind_method(D_METHOD("get_emission_operator"), &SpatialMaterial::get_emission_operator);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_binormal", "flip"), &BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_binormal"), &BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal);
- ClassDB::bind_method(D_METHOD("set_ao_light_affect", "amount"), &SpatialMaterial::set_ao_light_affect);
- ClassDB::bind_method(D_METHOD("get_ao_light_affect"), &SpatialMaterial::get_ao_light_affect);
+ ClassDB::bind_method(D_METHOD("set_grow", "amount"), &BaseMaterial3D::set_grow);
+ ClassDB::bind_method(D_METHOD("get_grow"), &BaseMaterial3D::get_grow);
- ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &SpatialMaterial::set_alpha_scissor_threshold);
- ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &SpatialMaterial::get_alpha_scissor_threshold);
+ ClassDB::bind_method(D_METHOD("set_emission_operator", "operator"), &BaseMaterial3D::set_emission_operator);
+ ClassDB::bind_method(D_METHOD("get_emission_operator"), &BaseMaterial3D::get_emission_operator);
- ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &SpatialMaterial::set_grow_enabled);
- ClassDB::bind_method(D_METHOD("is_grow_enabled"), &SpatialMaterial::is_grow_enabled);
+ ClassDB::bind_method(D_METHOD("set_ao_light_affect", "amount"), &BaseMaterial3D::set_ao_light_affect);
+ ClassDB::bind_method(D_METHOD("get_ao_light_affect"), &BaseMaterial3D::get_ao_light_affect);
- ClassDB::bind_method(D_METHOD("set_metallic_texture_channel", "channel"), &SpatialMaterial::set_metallic_texture_channel);
- ClassDB::bind_method(D_METHOD("get_metallic_texture_channel"), &SpatialMaterial::get_metallic_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &BaseMaterial3D::set_alpha_scissor_threshold);
+ ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &BaseMaterial3D::get_alpha_scissor_threshold);
- ClassDB::bind_method(D_METHOD("set_roughness_texture_channel", "channel"), &SpatialMaterial::set_roughness_texture_channel);
- ClassDB::bind_method(D_METHOD("get_roughness_texture_channel"), &SpatialMaterial::get_roughness_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &BaseMaterial3D::set_grow_enabled);
+ ClassDB::bind_method(D_METHOD("is_grow_enabled"), &BaseMaterial3D::is_grow_enabled);
- ClassDB::bind_method(D_METHOD("set_ao_texture_channel", "channel"), &SpatialMaterial::set_ao_texture_channel);
- ClassDB::bind_method(D_METHOD("get_ao_texture_channel"), &SpatialMaterial::get_ao_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_metallic_texture_channel", "channel"), &BaseMaterial3D::set_metallic_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_metallic_texture_channel"), &BaseMaterial3D::get_metallic_texture_channel);
- ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &SpatialMaterial::set_refraction_texture_channel);
- ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &SpatialMaterial::get_refraction_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_roughness_texture_channel", "channel"), &BaseMaterial3D::set_roughness_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_roughness_texture_channel"), &BaseMaterial3D::get_roughness_texture_channel);
- ClassDB::bind_method(D_METHOD("set_proximity_fade", "enabled"), &SpatialMaterial::set_proximity_fade);
- ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled"), &SpatialMaterial::is_proximity_fade_enabled);
+ ClassDB::bind_method(D_METHOD("set_ao_texture_channel", "channel"), &BaseMaterial3D::set_ao_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_ao_texture_channel"), &BaseMaterial3D::get_ao_texture_channel);
- ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &SpatialMaterial::set_proximity_fade_distance);
- ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &SpatialMaterial::get_proximity_fade_distance);
+ ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &BaseMaterial3D::set_refraction_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &BaseMaterial3D::get_refraction_texture_channel);
- ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &SpatialMaterial::set_distance_fade);
- ClassDB::bind_method(D_METHOD("get_distance_fade"), &SpatialMaterial::get_distance_fade);
+ ClassDB::bind_method(D_METHOD("set_proximity_fade", "enabled"), &BaseMaterial3D::set_proximity_fade);
+ ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled"), &BaseMaterial3D::is_proximity_fade_enabled);
- ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &SpatialMaterial::set_distance_fade_max_distance);
- ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &SpatialMaterial::get_distance_fade_max_distance);
+ ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &BaseMaterial3D::set_proximity_fade_distance);
+ ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &BaseMaterial3D::get_proximity_fade_distance);
- ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &SpatialMaterial::set_distance_fade_min_distance);
- ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &SpatialMaterial::get_distance_fade_min_distance);
+ ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &BaseMaterial3D::set_distance_fade);
+ ClassDB::bind_method(D_METHOD("get_distance_fade"), &BaseMaterial3D::get_distance_fade);
+
+ ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &BaseMaterial3D::set_distance_fade_max_distance);
+ ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &BaseMaterial3D::get_distance_fade_max_distance);
+
+ ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &BaseMaterial3D::set_distance_fade_min_distance);
+ ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance);
+
+ ADD_GROUP("Transparency", "");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,AlphaScissor,DepthPrePass"), "set_transparency", "get_transparency");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST);
+
+ ADD_GROUP("Shading", "");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,PerPixel,PerVertex"), "set_shading_mode", "get_shading_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT);
- ADD_GROUP("Flags", "flags_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_shadow_to_opacity"), "set_flag", "get_flag", FLAG_USE_SHADOW_TO_OPACITY);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_vertex_lighting"), "set_flag", "get_flag", FLAG_USE_VERTEX_LIGHTING);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_world_triplanar"), "set_flag", "get_flag", FLAG_TRIPLANAR_USE_WORLD);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_do_not_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_ensure_correct_normals"), "set_flag", "get_flag", FLAG_ENSURE_CORRECT_NORMALS);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR);
- ADD_GROUP("Parameters", "params_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never,Opaque Pre-Pass"), "set_depth_draw_mode", "get_depth_draw_mode");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_line_width", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_line_width", "get_line_width");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params_grow"), "set_grow_enabled", "is_grow_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_grow_amount", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_grow", "get_grow");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_use_alpha_scissor"), "set_flag", "get_flag", FLAG_USE_ALPHA_SCISSOR);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
- ADD_GROUP("Particles Anim", "particles_anim_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop");
-
ADD_GROUP("Albedo", "albedo_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ALBEDO);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
+
+ ADD_GROUP("ORM", "orm_");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orm_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ORM);
ADD_GROUP("Metallic", "metallic_");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_METALLIC);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "metallic", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_METALLIC);
ADD_PROPERTY(PropertyInfo(Variant::INT, "metallic_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_metallic_texture_channel", "get_metallic_texture_channel");
ADD_GROUP("Roughness", "roughness_");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ROUGHNESS);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ROUGHNESS);
ADD_PROPERTY(PropertyInfo(Variant::INT, "roughness_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_roughness_texture_channel", "get_roughness_texture_channel");
ADD_GROUP("Emission", "emission_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_enabled"), "set_feature", "get_feature", FEATURE_EMISSION);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_emission_energy", "get_emission_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_emission_energy", "get_emission_energy");
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_operator", PROPERTY_HINT_ENUM, "Add,Multiply"), "set_emission_operator", "get_emission_operator");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_on_uv2"), "set_flag", "get_flag", FLAG_EMISSION_ON_UV2);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_EMISSION);
ADD_GROUP("NormalMap", "normal_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "normal_enabled"), "set_feature", "get_feature", FEATURE_NORMAL_MAPPING);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_normal_scale", "get_normal_scale");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_normal_scale", "get_normal_scale");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_NORMAL);
ADD_GROUP("Rim", "rim_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "rim_enabled"), "set_feature", "get_feature", FEATURE_RIM);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "rim", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim", "get_rim");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "rim_tint", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim_tint", "get_rim_tint");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "rim_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_RIM);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rim", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim", "get_rim");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rim_tint", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim_tint", "get_rim_tint");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "rim_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_RIM);
ADD_GROUP("Clearcoat", "clearcoat_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "clearcoat_enabled"), "set_feature", "get_feature", FEATURE_CLEARCOAT);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "clearcoat", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat", "get_clearcoat");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "clearcoat_gloss", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat_gloss", "get_clearcoat_gloss");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_CLEARCOAT);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat", "get_clearcoat");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat_gloss", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat_gloss", "get_clearcoat_gloss");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_CLEARCOAT);
ADD_GROUP("Anisotropy", "anisotropy_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anisotropy_enabled"), "set_feature", "get_feature", FEATURE_ANISOTROPY);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "anisotropy", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_anisotropy", "get_anisotropy");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anisotropy_flowmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_FLOWMAP);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "anisotropy", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_anisotropy", "get_anisotropy");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anisotropy_flowmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_FLOWMAP);
ADD_GROUP("Ambient Occlusion", "ao_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled"), "set_feature", "get_feature", FEATURE_AMBIENT_OCCLUSION);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ao_light_affect", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao_light_affect", "get_ao_light_affect");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ao_light_affect", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao_light_affect", "get_ao_light_affect");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_on_uv2"), "set_flag", "get_flag", FLAG_AO_ON_UV2);
ADD_PROPERTY(PropertyInfo(Variant::INT, "ao_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_ao_texture_channel", "get_ao_texture_channel");
- ADD_GROUP("Depth", "depth_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "depth_enabled"), "set_feature", "get_feature", FEATURE_DEPTH_MAPPING);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_depth_scale", "get_depth_scale");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_deep_parallax"), "set_depth_deep_parallax", "is_depth_deep_parallax_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_min_layers", "get_depth_deep_parallax_min_layers");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_max_layers", "get_depth_deep_parallax_max_layers");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_tangent"), "set_depth_deep_parallax_flip_tangent", "get_depth_deep_parallax_flip_tangent");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_binormal"), "set_depth_deep_parallax_flip_binormal", "get_depth_deep_parallax_flip_binormal");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "depth_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DEPTH);
+ ADD_GROUP("Height", "heightmap_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_heightmap_scale", "get_heightmap_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_deep_parallax"), "set_heightmap_deep_parallax", "is_heightmap_deep_parallax_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_tangent"), "set_heightmap_deep_parallax_flip_tangent", "get_heightmap_deep_parallax_flip_tangent");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_binormal"), "set_heightmap_deep_parallax_flip_binormal", "get_heightmap_deep_parallax_flip_binormal");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_HEIGHTMAP);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_flip_texture"), "set_flag", "get_flag", FLAG_INVERT_HEIGHTMAP);
ADD_GROUP("Subsurf Scatter", "subsurf_scatter_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURACE_SCATTERING);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING);
-
- ADD_GROUP("Transmission", "transmission_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transmission_enabled"), "set_feature", "get_feature", FEATURE_TRANSMISSION);
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "transmission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_transmission", "get_transmission");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_TRANSMISSION);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_SCATTERING);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_skin_mode"), "set_flag", "get_flag", FLAG_SUBSURFACE_MODE_SKIN);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING);
+
+ ADD_SUBGROUP("Transmittance", "subsurf_scatter_transmittance_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_transmittance_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_TRANSMITTANCE);
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_curve", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_transmittance_curve", "get_transmittance_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost");
+
+ ADD_GROUP("Back Lighting", "backlight_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "backlight_enabled"), "set_feature", "get_feature", FEATURE_BACKLIGHT);
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "backlight", PROPERTY_HINT_COLOR_NO_ALPHA), "set_backlight", "get_backlight");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "backlight_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_BACKLIGHT);
ADD_GROUP("Refraction", "refraction_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_REFRACTION);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_REFRACTION);
ADD_PROPERTY(PropertyInfo(Variant::INT, "refraction_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_refraction_texture_channel", "get_refraction_texture_channel");
ADD_GROUP("Detail", "detail_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "detail_enabled"), "set_feature", "get_feature", FEATURE_DETAIL);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK);
ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_detail_blend_mode", "get_detail_blend_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_uv_layer", PROPERTY_HINT_ENUM, "UV1,UV2"), "set_detail_uv", "get_detail_uv");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL);
ADD_GROUP("UV1", "uv1_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_scale"), "set_uv1_scale", "get_uv1_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_offset"), "set_uv1_offset", "get_uv1_offset");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_TRIPLANAR);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv1_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "uv1_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_world_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_WORLD_TRIPLANAR);
ADD_GROUP("UV2", "uv2_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_scale"), "set_uv2_scale", "get_uv2_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_offset"), "set_uv2_offset", "get_uv2_offset");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_TRIPLANAR);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv2_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "uv2_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_world_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_WORLD_TRIPLANAR);
+
+ ADD_GROUP("Sampling", "texture_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapNearest,MipmapLinear,MipmapNearestAniso,MipmapLinearAniso"), "set_texture_filter", "get_texture_filter");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "texture_repeat"), "set_flag", "get_flag", FLAG_USE_TEXTURE_REPEAT);
+
+ ADD_GROUP("Shadows", "");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "shadow_to_opacity"), "set_flag", "get_flag", FLAG_USE_SHADOW_TO_OPACITY);
+
+ ADD_GROUP("Billboard", "billboard_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE);
+
+ ADD_GROUP("Particles Anim", "particles_anim_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop");
+ ADD_GROUP("Grow", "grow_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "grow"), "set_grow_enabled", "is_grow_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "grow_amount", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_grow", "get_grow");
+ ADD_GROUP("Transform", "");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size");
ADD_GROUP("Proximity Fade", "proximity_fade_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enable"), "set_proximity_fade", "is_proximity_fade_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_proximity_fade_distance", "get_proximity_fade_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_proximity_fade_distance", "get_proximity_fade_distance");
ADD_GROUP("Distance Fade", "distance_fade_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "distance_fade_mode", PROPERTY_HINT_ENUM, "Disabled,PixelAlpha,PixelDither,ObjectDither"), "set_distance_fade", "get_distance_fade");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_min_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_min_distance", "get_distance_fade_min_distance");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_max_distance", "get_distance_fade_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_min_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_min_distance", "get_distance_fade_min_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_max_distance", "get_distance_fade_max_distance");
BIND_ENUM_CONSTANT(TEXTURE_ALBEDO);
BIND_ENUM_CONSTANT(TEXTURE_METALLIC);
@@ -2250,28 +2389,49 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURE_CLEARCOAT);
BIND_ENUM_CONSTANT(TEXTURE_FLOWMAP);
BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION);
- BIND_ENUM_CONSTANT(TEXTURE_DEPTH);
+ BIND_ENUM_CONSTANT(TEXTURE_HEIGHTMAP);
BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING);
- BIND_ENUM_CONSTANT(TEXTURE_TRANSMISSION);
+ BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_TRANSMITTANCE);
+ BIND_ENUM_CONSTANT(TEXTURE_BACKLIGHT);
BIND_ENUM_CONSTANT(TEXTURE_REFRACTION);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_NORMAL);
+ BIND_ENUM_CONSTANT(TEXTURE_ORM);
BIND_ENUM_CONSTANT(TEXTURE_MAX);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_MAX);
+
BIND_ENUM_CONSTANT(DETAIL_UV_1);
BIND_ENUM_CONSTANT(DETAIL_UV_2);
- BIND_ENUM_CONSTANT(FEATURE_TRANSPARENT);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_DISABLED);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_SCISSOR);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_MAX);
+
+ BIND_ENUM_CONSTANT(SHADING_MODE_UNSHADED);
+ BIND_ENUM_CONSTANT(SHADING_MODE_PER_PIXEL);
+ BIND_ENUM_CONSTANT(SHADING_MODE_PER_VERTEX);
+ BIND_ENUM_CONSTANT(SHADING_MODE_MAX);
+
BIND_ENUM_CONSTANT(FEATURE_EMISSION);
BIND_ENUM_CONSTANT(FEATURE_NORMAL_MAPPING);
BIND_ENUM_CONSTANT(FEATURE_RIM);
BIND_ENUM_CONSTANT(FEATURE_CLEARCOAT);
BIND_ENUM_CONSTANT(FEATURE_ANISOTROPY);
BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION);
- BIND_ENUM_CONSTANT(FEATURE_DEPTH_MAPPING);
- BIND_ENUM_CONSTANT(FEATURE_SUBSURACE_SCATTERING);
- BIND_ENUM_CONSTANT(FEATURE_TRANSMISSION);
+ BIND_ENUM_CONSTANT(FEATURE_HEIGHT_MAPPING);
+ BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_SCATTERING);
+ BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_TRANSMITTANCE);
+ BIND_ENUM_CONSTANT(FEATURE_BACKLIGHT);
BIND_ENUM_CONSTANT(FEATURE_REFRACTION);
BIND_ENUM_CONSTANT(FEATURE_DETAIL);
BIND_ENUM_CONSTANT(FEATURE_MAX);
@@ -2284,14 +2444,11 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(DEPTH_DRAW_OPAQUE_ONLY);
BIND_ENUM_CONSTANT(DEPTH_DRAW_ALWAYS);
BIND_ENUM_CONSTANT(DEPTH_DRAW_DISABLED);
- BIND_ENUM_CONSTANT(DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
BIND_ENUM_CONSTANT(CULL_BACK);
BIND_ENUM_CONSTANT(CULL_FRONT);
BIND_ENUM_CONSTANT(CULL_DISABLED);
- BIND_ENUM_CONSTANT(FLAG_UNSHADED);
- BIND_ENUM_CONSTANT(FLAG_USE_VERTEX_LIGHTING);
BIND_ENUM_CONSTANT(FLAG_DISABLE_DEPTH_TEST);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR);
BIND_ENUM_CONSTANT(FLAG_SRGB_VERTEX_COLOR);
@@ -2300,15 +2457,17 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_BILLBOARD_KEEP_SCALE);
BIND_ENUM_CONSTANT(FLAG_UV1_USE_TRIPLANAR);
BIND_ENUM_CONSTANT(FLAG_UV2_USE_TRIPLANAR);
+ BIND_ENUM_CONSTANT(FLAG_UV1_USE_WORLD_TRIPLANAR);
+ BIND_ENUM_CONSTANT(FLAG_UV2_USE_WORLD_TRIPLANAR);
BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2);
BIND_ENUM_CONSTANT(FLAG_EMISSION_ON_UV2);
- BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR);
- BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
BIND_ENUM_CONSTANT(FLAG_DONT_RECEIVE_SHADOWS);
BIND_ENUM_CONSTANT(FLAG_DISABLE_AMBIENT_LIGHT);
- BIND_ENUM_CONSTANT(FLAG_ENSURE_CORRECT_NORMALS);
BIND_ENUM_CONSTANT(FLAG_USE_SHADOW_TO_OPACITY);
+ BIND_ENUM_CONSTANT(FLAG_USE_TEXTURE_REPEAT);
+ BIND_ENUM_CONSTANT(FLAG_INVERT_HEIGHTMAP);
+ BIND_ENUM_CONSTANT(FLAG_SUBSURFACE_MODE_SKIN);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
@@ -2343,10 +2502,12 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER);
}
-SpatialMaterial::SpatialMaterial() :
+BaseMaterial3D::BaseMaterial3D(bool p_orm) :
element(this) {
-
+ orm = p_orm;
// Initialize to the same values as the shader
+ transparency = TRANSPARENCY_DISABLED;
+ shading_mode = SHADING_MODE_PER_PIXEL;
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
set_specular(0.5);
set_roughness(1.0);
@@ -2359,11 +2520,14 @@ SpatialMaterial::SpatialMaterial() :
set_clearcoat(1);
set_clearcoat_gloss(0.5);
set_anisotropy(0);
- set_depth_scale(0.05);
+ set_heightmap_scale(0.05);
set_subsurface_scattering_strength(0);
- set_transmission(Color(0, 0, 0));
+ set_backlight(Color(0, 0, 0));
+ set_transmittance_color(Color(1, 1, 1, 1));
+ set_transmittance_depth(0.1);
+ set_transmittance_curve(1.0);
+ set_transmittance_boost(0.0);
set_refraction(0.05);
- set_line_width(1);
set_point_size(1);
set_uv1_offset(Vector3(0, 0, 0));
set_uv1_scale(Vector3(1, 1, 1));
@@ -2395,11 +2559,11 @@ SpatialMaterial::SpatialMaterial() :
set_grow(0.0);
deep_parallax = false;
- depth_parallax_flip_tangent = false;
- depth_parallax_flip_binormal = false;
- set_depth_deep_parallax_min_layers(8);
- set_depth_deep_parallax_max_layers(32);
- set_depth_deep_parallax_flip_tangent(false); //also sets binormal
+ heightmap_parallax_flip_tangent = false;
+ heightmap_parallax_flip_binormal = false;
+ set_heightmap_deep_parallax_min_layers(8);
+ set_heightmap_deep_parallax_max_layers(32);
+ set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal
detail_uv = DETAIL_UV_1;
blend_mode = BLEND_MODE_MIX;
@@ -2407,8 +2571,10 @@ SpatialMaterial::SpatialMaterial() :
depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY;
cull_mode = CULL_BACK;
for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = 0;
+ flags[i] = false;
}
+ flags[FLAG_USE_TEXTURE_REPEAT] = true;
+
diffuse_mode = DIFFUSE_BURLEY;
specular_mode = SPECULAR_SCHLICK_GGX;
@@ -2416,27 +2582,116 @@ SpatialMaterial::SpatialMaterial() :
features[i] = false;
}
- current_key.key = 0;
+ current_key.key0 = 0;
+ current_key.key1 = 0;
current_key.invalid_key = 1;
+ texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
_queue_shader_change();
}
-SpatialMaterial::~SpatialMaterial() {
-
- if (material_mutex)
- material_mutex->lock();
+BaseMaterial3D::~BaseMaterial3D() {
+ MutexLock lock(material_mutex);
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
if (shader_map[current_key].users == 0) {
//deallocate shader, as it's no longer in use
- VS::get_singleton()->free(shader_map[current_key].shader);
+ RS::get_singleton()->free(shader_map[current_key].shader);
shader_map.erase(current_key);
}
- VS::get_singleton()->material_set_shader(_get_material(), RID());
+ RS::get_singleton()->material_set_shader(_get_material(), RID());
+ }
+}
+
+//////////////////////
+
+#ifndef DISABLE_DEPRECATED
+// Kept for compatibility from 3.x to 4.0.
+bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "flags_transparent") {
+ bool transparent = p_value;
+ if (transparent) {
+ set_transparency(TRANSPARENCY_ALPHA);
+ }
+ return true;
+ } else if (p_name == "flags_unshaded") {
+ bool unshaded = p_value;
+ if (unshaded) {
+ set_shading_mode(SHADING_MODE_UNSHADED);
+ }
+ return true;
+ } else if (p_name == "flags_vertex_lighting") {
+ bool vertex_lit = p_value;
+ if (vertex_lit && get_shading_mode() != SHADING_MODE_UNSHADED) {
+ set_shading_mode(SHADING_MODE_PER_VERTEX);
+ }
+ return true;
+ } else if (p_name == "params_use_alpha_scissor") {
+ bool use_scissor = p_value;
+ if (use_scissor) {
+ set_transparency(TRANSPARENCY_ALPHA_SCISSOR);
+ }
+ return true;
+ } else if (p_name == "params_depth_draw_mode") {
+ int mode = p_value;
+ if (mode == 3) {
+ set_transparency(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
+ }
+ return true;
+ } else if (p_name == "depth_enabled") {
+ bool enabled = p_value;
+ if (enabled) {
+ set_feature(FEATURE_HEIGHT_MAPPING, true);
+ set_flag(FLAG_INVERT_HEIGHTMAP, true);
+ }
+ return true;
+ } else {
+ static const Pair<const char *, const char *> remaps[] = {
+ { "flags_use_shadow_to_opacity", "shadow_to_opacity" },
+ { "flags_use_shadow_to_opacity", "shadow_to_opacity" },
+ { "flags_no_depth_test", "no_depth_test" },
+ { "flags_use_point_size", "use_point_size" },
+ { "flags_fixed_size", "fixed_Size" },
+ { "flags_albedo_tex_force_srg", "albedo_tex_force_srgb" },
+ { "flags_do_not_receive_shadows", "disable_receive_shadows" },
+ { "flags_disable_ambient_light", "disable_ambient_light" },
+ { "params_diffuse_mode", "diffuse_mode" },
+ { "params_specular_mode", "specular_mode" },
+ { "params_blend_mode", "blend_mode" },
+ { "params_cull_mode", "cull_mode" },
+ { "params_depth_draw_mode", "params_depth_draw_mode" },
+ { "params_point_size", "point_size" },
+ { "params_billboard_mode", "billboard_mode" },
+ { "params_billboard_keep_scale", "billboard_keep_scale" },
+ { "params_grow", "grow" },
+ { "params_grow_amount", "grow_amount" },
+ { "params_alpha_scissor_threshold", "alpha_scissor_threshold" },
+
+ { "depth_scale", "heightmap_scale" },
+ { "depth_deep_parallax", "heightmap_deep_parallax" },
+ { "depth_min_layers", "heightmap_min_layers" },
+ { "depth_max_layers", "heightmap_max_layers" },
+ { "depth_flip_tangent", "heightmap_flip_tangent" },
+ { "depth_flip_binormal", "heightmap_flip_binormal" },
+ { "depth_texture", "heightmap_texture" },
+
+ { nullptr, nullptr },
+ };
+
+ int idx = 0;
+ while (remaps[idx].first) {
+ if (p_name == remaps[idx].first) {
+ set(remaps[idx].second, p_value);
+ return true;
+ }
+ idx++;
+ }
+
+ print_line("remapped parameter not found: " + String(p_name));
+ return true;
}
- if (material_mutex)
- material_mutex->unlock();
+ return false;
}
+#endif // DISABLE_DEPRECATED
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 8e66011bec..b5bdd77eb5 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -35,11 +35,10 @@
#include "core/self_list.h"
#include "scene/resources/shader.h"
#include "scene/resources/texture.h"
-#include "servers/visual/shader_language.h"
-#include "servers/visual_server.h"
+#include "servers/rendering/shader_language.h"
+#include "servers/rendering_server.h"
class Material : public Resource {
-
GDCLASS(Material, Resource);
RES_BASE_EXTENSION("material")
OBJ_SAVE_TYPE(Material);
@@ -53,12 +52,12 @@ protected:
static void _bind_methods();
virtual bool _can_do_next_pass() const { return false; }
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
enum {
- RENDER_PRIORITY_MAX = VS::MATERIAL_RENDER_PRIORITY_MAX,
- RENDER_PRIORITY_MIN = VS::MATERIAL_RENDER_PRIORITY_MIN,
+ RENDER_PRIORITY_MAX = RS::MATERIAL_RENDER_PRIORITY_MAX,
+ RENDER_PRIORITY_MIN = RS::MATERIAL_RENDER_PRIORITY_MIN,
};
void set_next_pass(const Ref<Material> &p_pass);
Ref<Material> get_next_pass() const;
@@ -66,7 +65,7 @@ public:
void set_render_priority(int p_priority);
int get_render_priority() const;
- virtual RID get_rid() const;
+ virtual RID get_rid() const override;
virtual Shader::Mode get_shader_mode() const = 0;
Material();
@@ -74,7 +73,6 @@ public:
};
class ShaderMaterial : public Material {
-
GDCLASS(ShaderMaterial, Material);
Ref<Shader> shader;
@@ -87,9 +85,9 @@ protected:
static void _bind_methods();
- void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
+ void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
- virtual bool _can_do_next_pass() const;
+ virtual bool _can_do_next_pass() const override;
void _shader_changed();
@@ -100,15 +98,16 @@ public:
void set_shader_param(const StringName &p_param, const Variant &p_value);
Variant get_shader_param(const StringName &p_param) const;
- virtual Shader::Mode get_shader_mode() const;
+ virtual Shader::Mode get_shader_mode() const override;
ShaderMaterial();
~ShaderMaterial();
};
-class SpatialMaterial : public Material {
+class StandardMaterial3D;
- GDCLASS(SpatialMaterial, Material);
+class BaseMaterial3D : public Material {
+ GDCLASS(BaseMaterial3D, Material);
public:
enum TextureParam {
@@ -121,33 +120,60 @@ public:
TEXTURE_CLEARCOAT,
TEXTURE_FLOWMAP,
TEXTURE_AMBIENT_OCCLUSION,
- TEXTURE_DEPTH,
+ TEXTURE_HEIGHTMAP,
TEXTURE_SUBSURFACE_SCATTERING,
- TEXTURE_TRANSMISSION,
+ TEXTURE_SUBSURFACE_TRANSMITTANCE,
+ TEXTURE_BACKLIGHT,
TEXTURE_REFRACTION,
TEXTURE_DETAIL_MASK,
TEXTURE_DETAIL_ALBEDO,
TEXTURE_DETAIL_NORMAL,
+ TEXTURE_ORM,
TEXTURE_MAX
};
+ enum TextureFilter {
+ TEXTURE_FILTER_NEAREST,
+ TEXTURE_FILTER_LINEAR,
+ TEXTURE_FILTER_NEAREST_WITH_MIPMAPS,
+ TEXTURE_FILTER_LINEAR_WITH_MIPMAPS,
+ TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC,
+ TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC,
+ TEXTURE_FILTER_MAX
+ };
+
enum DetailUV {
DETAIL_UV_1,
DETAIL_UV_2
};
+ enum Transparency {
+ TRANSPARENCY_DISABLED,
+ TRANSPARENCY_ALPHA,
+ TRANSPARENCY_ALPHA_SCISSOR,
+ TRANSPARENCY_ALPHA_DEPTH_PRE_PASS,
+ TRANSPARENCY_MAX,
+ };
+
+ enum ShadingMode {
+ SHADING_MODE_UNSHADED,
+ SHADING_MODE_PER_PIXEL,
+ SHADING_MODE_PER_VERTEX,
+ SHADING_MODE_MAX
+ };
+
enum Feature {
- FEATURE_TRANSPARENT,
FEATURE_EMISSION,
FEATURE_NORMAL_MAPPING,
FEATURE_RIM,
FEATURE_CLEARCOAT,
FEATURE_ANISOTROPY,
FEATURE_AMBIENT_OCCLUSION,
- FEATURE_DEPTH_MAPPING,
- FEATURE_SUBSURACE_SCATTERING,
- FEATURE_TRANSMISSION,
+ FEATURE_HEIGHT_MAPPING,
+ FEATURE_SUBSURFACE_SCATTERING,
+ FEATURE_SUBSURFACE_TRANSMITTANCE,
+ FEATURE_BACKLIGHT,
FEATURE_REFRACTION,
FEATURE_DETAIL,
FEATURE_MAX
@@ -164,8 +190,6 @@ public:
DEPTH_DRAW_OPAQUE_ONLY,
DEPTH_DRAW_ALWAYS,
DEPTH_DRAW_DISABLED,
- DEPTH_DRAW_ALPHA_OPAQUE_PREPASS
-
};
enum CullMode {
@@ -175,8 +199,6 @@ public:
};
enum Flags {
- FLAG_UNSHADED,
- FLAG_USE_VERTEX_LIGHTING,
FLAG_DISABLE_DEPTH_TEST,
FLAG_ALBEDO_FROM_VERTEX_COLOR,
FLAG_SRGB_VERTEX_COLOR,
@@ -185,15 +207,17 @@ public:
FLAG_BILLBOARD_KEEP_SCALE,
FLAG_UV1_USE_TRIPLANAR,
FLAG_UV2_USE_TRIPLANAR,
- FLAG_TRIPLANAR_USE_WORLD,
+ FLAG_UV1_USE_WORLD_TRIPLANAR,
+ FLAG_UV2_USE_WORLD_TRIPLANAR,
FLAG_AO_ON_UV2,
FLAG_EMISSION_ON_UV2,
- FLAG_USE_ALPHA_SCISSOR,
FLAG_ALBEDO_TEXTURE_FORCE_SRGB,
FLAG_DONT_RECEIVE_SHADOWS,
- FLAG_ENSURE_CORRECT_NORMALS,
FLAG_DISABLE_AMBIENT_LIGHT,
FLAG_USE_SHADOW_TO_OPACITY,
+ FLAG_USE_TEXTURE_REPEAT,
+ FLAG_INVERT_HEIGHTMAP,
+ FLAG_SUBSURFACE_MODE_SKIN,
FLAG_MAX
};
@@ -242,14 +266,13 @@ public:
private:
union MaterialKey {
-
struct {
- uint64_t feature_mask : 12;
+ uint64_t feature_mask : FEATURE_MAX;
uint64_t detail_uv : 1;
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 19;
+ uint64_t flags : FLAG_MAX;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 3;
@@ -260,14 +283,22 @@ private:
uint64_t proximity_fade : 1;
uint64_t distance_fade : 2;
uint64_t emission_op : 1;
- uint64_t texture_metallic : 1;
- uint64_t texture_roughness : 1;
+ uint64_t texture_filter : 3;
+ uint64_t transparency : 2;
+ uint64_t shading_mode : 2;
+ uint64_t roughness_channel : 3;
};
- uint64_t key;
+ struct {
+ uint64_t key0;
+ uint64_t key1;
+ };
+ bool operator==(const MaterialKey &p_key) const {
+ return (key0 == p_key.key0) && (key1 == p_key.key1);
+ }
bool operator<(const MaterialKey &p_key) const {
- return key < p_key.key;
+ return (key0 == p_key.key0) ? (key1 < p_key.key1) : (key0 < p_key.key0);
}
};
@@ -281,9 +312,9 @@ private:
MaterialKey current_key;
_FORCE_INLINE_ MaterialKey _compute_key() const {
-
MaterialKey mk;
- mk.key = 0;
+ mk.key0 = 0;
+ mk.key1 = 0;
for (int i = 0; i < FEATURE_MAX; i++) {
if (features[i]) {
mk.feature_mask |= ((uint64_t)1 << i);
@@ -293,6 +324,10 @@ private:
mk.blend_mode = blend_mode;
mk.depth_draw_mode = depth_draw_mode;
mk.cull_mode = cull_mode;
+ mk.texture_filter = texture_filter;
+ mk.transparency = transparency;
+ mk.shading_mode = shading_mode;
+ mk.roughness_channel = roughness_texture_channel;
for (int i = 0; i < FLAG_MAX; i++) {
if (flags[i]) {
mk.flags |= ((uint64_t)1 << i);
@@ -307,8 +342,6 @@ private:
mk.proximity_fade = proximity_fade_enabled;
mk.distance_fade = distance_fade;
mk.emission_op = emission_op;
- mk.texture_metallic = textures[TEXTURE_METALLIC].is_valid() ? 1 : 0;
- mk.texture_roughness = textures[TEXTURE_ROUGHNESS].is_valid() ? 1 : 0;
return mk;
}
@@ -326,9 +359,13 @@ private:
StringName clearcoat;
StringName clearcoat_gloss;
StringName anisotropy;
- StringName depth_scale;
+ StringName heightmap_scale;
StringName subsurface_scattering_strength;
- StringName transmission;
+ StringName transmittance_color;
+ StringName transmittance_curve;
+ StringName transmittance_depth;
+ StringName transmittance_boost;
+ StringName backlight;
StringName refraction;
StringName point_size;
StringName uv1_scale;
@@ -338,9 +375,9 @@ private:
StringName particles_anim_h_frames;
StringName particles_anim_v_frames;
StringName particles_anim_loop;
- StringName depth_min_layers;
- StringName depth_max_layers;
- StringName depth_flip;
+ StringName heightmap_min_layers;
+ StringName heightmap_max_layers;
+ StringName heightmap_flip;
StringName uv1_blend_sharpness;
StringName uv2_blend_sharpness;
StringName grow;
@@ -350,27 +387,28 @@ private:
StringName ao_light_affect;
StringName metallic_texture_channel;
- StringName roughness_texture_channel;
StringName ao_texture_channel;
StringName clearcoat_texture_channel;
StringName rim_texture_channel;
- StringName depth_texture_channel;
+ StringName heightmap_texture_channel;
StringName refraction_texture_channel;
StringName alpha_scissor_threshold;
StringName texture_names[TEXTURE_MAX];
};
- static Mutex *material_mutex;
- static SelfList<SpatialMaterial>::List *dirty_materials;
+ static Mutex material_mutex;
+ static SelfList<BaseMaterial3D>::List *dirty_materials;
static ShaderNames *shader_names;
- SelfList<SpatialMaterial> element;
+ SelfList<BaseMaterial3D> element;
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
_FORCE_INLINE_ bool _is_shader_dirty() const;
+ bool orm;
+
Color albedo;
float specular;
float metallic;
@@ -383,11 +421,16 @@ private:
float clearcoat;
float clearcoat_gloss;
float anisotropy;
- float depth_scale;
+ float heightmap_scale;
float subsurface_scattering_strength;
- Color transmission;
+ float transmittance_amount;
+ Color transmittance_color;
+ float transmittance_depth;
+ float transmittance_curve;
+ float transmittance_boost;
+
+ Color backlight;
float refraction;
- float line_width;
float point_size;
float alpha_scissor_threshold;
bool grow_enabled;
@@ -396,6 +439,10 @@ private:
int particles_anim_h_frames;
int particles_anim_v_frames;
bool particles_anim_loop;
+ Transparency transparency;
+ ShadingMode shading_mode;
+
+ TextureFilter texture_filter;
Vector3 uv1_scale;
Vector3 uv1_offset;
@@ -410,8 +457,8 @@ private:
bool deep_parallax;
int deep_parallax_min_layers;
int deep_parallax_max_layers;
- bool depth_parallax_flip_tangent;
- bool depth_parallax_flip_binormal;
+ bool heightmap_parallax_flip_tangent;
+ bool heightmap_parallax_flip_binormal;
bool proximity_fade_enabled;
float proximity_fade_distance;
@@ -437,20 +484,20 @@ private:
bool features[FEATURE_MAX];
- Ref<Texture> textures[TEXTURE_MAX];
+ Ref<Texture2D> textures[TEXTURE_MAX];
_FORCE_INLINE_ void _validate_feature(const String &text, Feature feature, PropertyInfo &property) const;
static const int MAX_MATERIALS_FOR_2D = 128;
- static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff
+ static Ref<StandardMaterial3D> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff
void _validate_high_end(const String &text, PropertyInfo &property) const;
protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
- virtual bool _can_do_next_pass() const { return true; }
+ void _validate_property(PropertyInfo &property) const override;
+ virtual bool _can_do_next_pass() const override { return true; }
public:
void set_albedo(const Color &p_albedo);
@@ -492,39 +539,54 @@ public:
void set_anisotropy(float p_anisotropy);
float get_anisotropy() const;
- void set_depth_scale(float p_depth_scale);
- float get_depth_scale() const;
+ void set_heightmap_scale(float p_heightmap_scale);
+ float get_heightmap_scale() const;
- void set_depth_deep_parallax(bool p_enable);
- bool is_depth_deep_parallax_enabled() const;
+ void set_heightmap_deep_parallax(bool p_enable);
+ bool is_heightmap_deep_parallax_enabled() const;
- void set_depth_deep_parallax_min_layers(int p_layer);
- int get_depth_deep_parallax_min_layers() const;
+ void set_heightmap_deep_parallax_min_layers(int p_layer);
+ int get_heightmap_deep_parallax_min_layers() const;
- void set_depth_deep_parallax_max_layers(int p_layer);
- int get_depth_deep_parallax_max_layers() const;
+ void set_heightmap_deep_parallax_max_layers(int p_layer);
+ int get_heightmap_deep_parallax_max_layers() const;
- void set_depth_deep_parallax_flip_tangent(bool p_flip);
- bool get_depth_deep_parallax_flip_tangent() const;
+ void set_heightmap_deep_parallax_flip_tangent(bool p_flip);
+ bool get_heightmap_deep_parallax_flip_tangent() const;
- void set_depth_deep_parallax_flip_binormal(bool p_flip);
- bool get_depth_deep_parallax_flip_binormal() const;
+ void set_heightmap_deep_parallax_flip_binormal(bool p_flip);
+ bool get_heightmap_deep_parallax_flip_binormal() const;
void set_subsurface_scattering_strength(float p_subsurface_scattering_strength);
float get_subsurface_scattering_strength() const;
- void set_transmission(const Color &p_transmission);
- Color get_transmission() const;
+ void set_transmittance_color(const Color &p_color);
+ Color get_transmittance_color() const;
+
+ void set_transmittance_depth(float p_depth);
+ float get_transmittance_depth() const;
+
+ void set_transmittance_curve(float p_curve);
+ float get_transmittance_curve() const;
+
+ void set_transmittance_boost(float p_boost);
+ float get_transmittance_boost() const;
+
+ void set_backlight(const Color &p_backlight);
+ Color get_backlight() const;
void set_refraction(float p_refraction);
float get_refraction() const;
- void set_line_width(float p_line_width);
- float get_line_width() const;
-
void set_point_size(float p_point_size);
float get_point_size() const;
+ void set_transparency(Transparency p_transparency);
+ Transparency get_transparency() const;
+
+ void set_shading_mode(ShadingMode p_shading_mode);
+ ShadingMode get_shading_mode() const;
+
void set_detail_uv(DetailUV p_detail_uv);
DetailUV get_detail_uv() const;
@@ -549,10 +611,13 @@ public:
void set_flag(Flags p_flag, bool p_enabled);
bool get_flag(Flags p_flag) const;
- void set_texture(TextureParam p_param, const Ref<Texture> &p_texture);
- Ref<Texture> get_texture(TextureParam p_param) const;
+ void set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture(TextureParam p_param) const;
// Used only for shader material conversion
- Ref<Texture> get_texture_by_name(StringName p_name) const;
+ Ref<Texture2D> get_texture_by_name(StringName p_name) const;
+
+ void set_texture_filter(TextureFilter p_filter);
+ TextureFilter get_texture_filter() const;
void set_feature(Feature p_feature, bool p_enabled);
bool get_feature(Feature p_feature) const;
@@ -632,25 +697,48 @@ public:
RID get_shader_rid() const;
- virtual Shader::Mode get_shader_mode() const;
+ virtual Shader::Mode get_shader_mode() const override;
- SpatialMaterial();
- virtual ~SpatialMaterial();
+ BaseMaterial3D(bool p_orm);
+ virtual ~BaseMaterial3D();
};
-VARIANT_ENUM_CAST(SpatialMaterial::TextureParam)
-VARIANT_ENUM_CAST(SpatialMaterial::DetailUV)
-VARIANT_ENUM_CAST(SpatialMaterial::Feature)
-VARIANT_ENUM_CAST(SpatialMaterial::BlendMode)
-VARIANT_ENUM_CAST(SpatialMaterial::DepthDrawMode)
-VARIANT_ENUM_CAST(SpatialMaterial::CullMode)
-VARIANT_ENUM_CAST(SpatialMaterial::Flags)
-VARIANT_ENUM_CAST(SpatialMaterial::DiffuseMode)
-VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode)
-VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode)
-VARIANT_ENUM_CAST(SpatialMaterial::TextureChannel)
-VARIANT_ENUM_CAST(SpatialMaterial::EmissionOperator)
-VARIANT_ENUM_CAST(SpatialMaterial::DistanceFadeMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::TextureParam)
+VARIANT_ENUM_CAST(BaseMaterial3D::TextureFilter)
+VARIANT_ENUM_CAST(BaseMaterial3D::ShadingMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::Transparency)
+VARIANT_ENUM_CAST(BaseMaterial3D::DetailUV)
+VARIANT_ENUM_CAST(BaseMaterial3D::Feature)
+VARIANT_ENUM_CAST(BaseMaterial3D::BlendMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::DepthDrawMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::CullMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::Flags)
+VARIANT_ENUM_CAST(BaseMaterial3D::DiffuseMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::SpecularMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::BillboardMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::TextureChannel)
+VARIANT_ENUM_CAST(BaseMaterial3D::EmissionOperator)
+VARIANT_ENUM_CAST(BaseMaterial3D::DistanceFadeMode)
+
+class StandardMaterial3D : public BaseMaterial3D {
+ GDCLASS(StandardMaterial3D, BaseMaterial3D)
+protected:
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
+ bool _set(const StringName &p_name, const Variant &p_value);
+#endif
+
+public:
+ StandardMaterial3D() :
+ BaseMaterial3D(false) {}
+};
+
+class ORMMaterial3D : public BaseMaterial3D {
+ GDCLASS(ORMMaterial3D, BaseMaterial3D)
+public:
+ ORMMaterial3D() :
+ BaseMaterial3D(true) {}
+};
//////////////////////
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 0599920303..10f0a040d0 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -31,61 +31,59 @@
#include "mesh.h"
#include "core/pair.h"
-#include "scene/resources/concave_polygon_shape.h"
-#include "scene/resources/convex_polygon_shape.h"
+#include "scene/resources/concave_polygon_shape_3d.h"
+#include "scene/resources/convex_polygon_shape_3d.h"
#include "surface_tool.h"
#include <stdlib.h>
-Mesh::ConvexDecompositionFunc Mesh::convex_composition_function = NULL;
+Mesh::ConvexDecompositionFunc Mesh::convex_composition_function = nullptr;
Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
-
- if (triangle_mesh.is_valid())
+ if (triangle_mesh.is_valid()) {
return triangle_mesh;
+ }
int facecount = 0;
for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) {
continue;
+ }
if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
-
facecount += surface_get_array_index_len(i);
} else {
-
facecount += surface_get_array_len(i);
}
}
- if (facecount == 0 || (facecount % 3) != 0)
+ if (facecount == 0 || (facecount % 3) != 0) {
return triangle_mesh;
+ }
- PoolVector<Vector3> faces;
+ Vector<Vector3> faces;
faces.resize(facecount);
- PoolVector<Vector3>::Write facesw = faces.write();
+ Vector3 *facesw = faces.ptrw();
int widx = 0;
for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) {
continue;
+ }
Array a = surface_get_arrays(i);
ERR_FAIL_COND_V(a.empty(), Ref<TriangleMesh>());
int vc = surface_get_array_len(i);
- PoolVector<Vector3> vertices = a[ARRAY_VERTEX];
- PoolVector<Vector3>::Read vr = vertices.read();
+ Vector<Vector3> vertices = a[ARRAY_VERTEX];
+ const Vector3 *vr = vertices.ptr();
if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
-
int ic = surface_get_array_index_len(i);
- PoolVector<int> indices = a[ARRAY_INDEX];
- PoolVector<int>::Read ir = indices.read();
+ Vector<int> indices = a[ARRAY_INDEX];
+ const int *ir = indices.ptr();
for (int j = 0; j < ic; j++) {
int index = ir[j];
@@ -93,14 +91,12 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
}
} else {
-
- for (int j = 0; j < vc; j++)
+ for (int j = 0; j < vc; j++) {
facesw[widx++] = vr[j];
+ }
}
}
- facesw.release();
-
triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
triangle_mesh->create(faces);
@@ -108,25 +104,25 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
}
void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) {
-
if (debug_lines.size() > 0) {
r_lines = debug_lines;
return;
}
Ref<TriangleMesh> tm = generate_triangle_mesh();
- if (tm.is_null())
+ if (tm.is_null()) {
return;
+ }
- PoolVector<int> triangle_indices;
+ Vector<int> triangle_indices;
tm->get_indices(&triangle_indices);
const int triangles_num = tm->get_triangles().size();
- PoolVector<Vector3> vertices = tm->get_vertices();
+ Vector<Vector3> vertices = tm->get_vertices();
debug_lines.resize(tm->get_triangles().size() * 6); // 3 lines x 2 points each line
- PoolVector<int>::Read ind_r = triangle_indices.read();
- PoolVector<Vector3>::Read ver_r = vertices.read();
+ const int *ind_r = triangle_indices.ptr();
+ const Vector3 *ver_r = vertices.ptr();
for (int j = 0, x = 0, i = 0; i < triangles_num; j += 6, x += 3, ++i) {
// Triangle line 1
debug_lines.write[j + 0] = ver_r[ind_r[x + 0]];
@@ -143,12 +139,14 @@ void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) {
r_lines = debug_lines;
}
+
void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
Ref<TriangleMesh> tm = generate_triangle_mesh();
- if (tm.is_null())
+ if (tm.is_null()) {
return;
+ }
- PoolVector<Vector3> vertices = tm->get_vertices();
+ Vector<Vector3> vertices = tm->get_vertices();
int vertices_size = vertices.size();
r_points.resize(vertices_size);
@@ -159,32 +157,32 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
bool Mesh::surface_is_softbody_friendly(int p_idx) const {
const uint32_t surface_format = surface_get_format(p_idx);
- return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_VERTEX)) && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL)));
+ return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL)));
}
-PoolVector<Face3> Mesh::get_faces() const {
-
+Vector<Face3> Mesh::get_faces() const {
Ref<TriangleMesh> tm = generate_triangle_mesh();
- if (tm.is_valid())
+ if (tm.is_valid()) {
return tm->get_faces();
- return PoolVector<Face3>();
+ }
+ return Vector<Face3>();
/*
for (int i=0;i<surfaces.size();i++) {
- if (VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != VisualServer::PRIMITIVE_TRIANGLES )
+ if (RenderingServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != RenderingServer::PRIMITIVE_TRIANGLES )
continue;
- PoolVector<int> indices;
- PoolVector<Vector3> vertices;
+ Vector<int> indices;
+ Vector<Vector3> vertices;
- vertices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_VERTEX);
+ vertices=RenderingServer::get_singleton()->mesh_surface_get_array(mesh, i,RenderingServer::ARRAY_VERTEX);
- int len=VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i);
+ int len=RenderingServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i);
bool has_indices;
if (len>0) {
- indices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_INDEX);
+ indices=RenderingServer::get_singleton()->mesh_surface_get_array(mesh, i,RenderingServer::ARRAY_INDEX);
has_indices=true;
} else {
@@ -196,10 +194,10 @@ PoolVector<Face3> Mesh::get_faces() const {
if (len<=0)
continue;
- PoolVector<int>::Read indicesr = indices.read();
+ const int* indicesr = indices.ptr();
const int *indicesptr = indicesr.ptr();
- PoolVector<Vector3>::Read verticesr = vertices.read();
+ const Vector3* verticesr = vertices.ptr();
const Vector3 *verticesptr = verticesr.ptr();
int old_faces=faces.size();
@@ -207,7 +205,7 @@ PoolVector<Face3> Mesh::get_faces() const {
faces.resize(new_faces);
- PoolVector<Face3>::Write facesw = faces.write();
+ Face3* facesw = faces.ptrw();
Face3 *facesptr=facesw.ptr();
@@ -228,64 +226,60 @@ PoolVector<Face3> Mesh::get_faces() const {
*/
}
-Ref<Shape> Mesh::create_convex_shape() const {
-
- PoolVector<Vector3> vertices;
+Ref<Shape3D> Mesh::create_convex_shape() const {
+ Vector<Vector3> vertices;
for (int i = 0; i < get_surface_count(); i++) {
-
Array a = surface_get_arrays(i);
- ERR_FAIL_COND_V(a.empty(), Ref<ConvexPolygonShape>());
- PoolVector<Vector3> v = a[ARRAY_VERTEX];
+ ERR_FAIL_COND_V(a.empty(), Ref<ConvexPolygonShape3D>());
+ Vector<Vector3> v = a[ARRAY_VERTEX];
vertices.append_array(v);
}
- Ref<ConvexPolygonShape> shape = memnew(ConvexPolygonShape);
+ Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D);
shape->set_points(vertices);
return shape;
}
-Ref<Shape> Mesh::create_trimesh_shape() const {
-
- PoolVector<Face3> faces = get_faces();
- if (faces.size() == 0)
- return Ref<Shape>();
+Ref<Shape3D> Mesh::create_trimesh_shape() const {
+ Vector<Face3> faces = get_faces();
+ if (faces.size() == 0) {
+ return Ref<Shape3D>();
+ }
- PoolVector<Vector3> face_points;
+ Vector<Vector3> face_points;
face_points.resize(faces.size() * 3);
- for (int i = 0; i < face_points.size(); i++) {
-
+ for (int i = 0; i < face_points.size(); i += 3) {
Face3 f = faces.get(i / 3);
- face_points.set(i, f.vertex[i % 3]);
+ face_points.set(i, f.vertex[0]);
+ face_points.set(i + 1, f.vertex[1]);
+ face_points.set(i + 2, f.vertex[2]);
}
- Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape);
+ Ref<ConcavePolygonShape3D> shape = memnew(ConcavePolygonShape3D);
shape->set_faces(face_points);
return shape;
}
Ref<Mesh> Mesh::create_outline(float p_margin) const {
-
Array arrays;
int index_accum = 0;
for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) {
continue;
+ }
Array a = surface_get_arrays(i);
ERR_FAIL_COND_V(a.empty(), Ref<ArrayMesh>());
if (i == 0) {
arrays = a;
- PoolVector<Vector3> v = a[ARRAY_VERTEX];
+ Vector<Vector3> v = a[ARRAY_VERTEX];
index_accum += v.size();
} else {
-
int vcount = 0;
for (int j = 0; j < arrays.size(); j++) {
-
if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) {
//mismatch, do not use
arrays[j] = Variant();
@@ -293,14 +287,13 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
}
switch (j) {
-
case ARRAY_VERTEX:
case ARRAY_NORMAL: {
-
- PoolVector<Vector3> dst = arrays[j];
- PoolVector<Vector3> src = a[j];
- if (j == ARRAY_VERTEX)
+ Vector<Vector3> dst = arrays[j];
+ Vector<Vector3> src = a[j];
+ if (j == ARRAY_VERTEX) {
vcount = src.size();
+ }
if (dst.size() == 0 || src.size() == 0) {
arrays[j] = Variant();
continue;
@@ -311,9 +304,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
case ARRAY_TANGENT:
case ARRAY_BONES:
case ARRAY_WEIGHTS: {
-
- PoolVector<real_t> dst = arrays[j];
- PoolVector<real_t> src = a[j];
+ Vector<real_t> dst = arrays[j];
+ Vector<real_t> src = a[j];
if (dst.size() == 0 || src.size() == 0) {
arrays[j] = Variant();
continue;
@@ -323,8 +315,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
} break;
case ARRAY_COLOR: {
- PoolVector<Color> dst = arrays[j];
- PoolVector<Color> src = a[j];
+ Vector<Color> dst = arrays[j];
+ Vector<Color> src = a[j];
if (dst.size() == 0 || src.size() == 0) {
arrays[j] = Variant();
continue;
@@ -335,8 +327,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
} break;
case ARRAY_TEX_UV:
case ARRAY_TEX_UV2: {
- PoolVector<Vector2> dst = arrays[j];
- PoolVector<Vector2> src = a[j];
+ Vector<Vector2> dst = arrays[j];
+ Vector<Vector2> src = a[j];
if (dst.size() == 0 || src.size() == 0) {
arrays[j] = Variant();
continue;
@@ -346,15 +338,15 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
} break;
case ARRAY_INDEX: {
- PoolVector<int> dst = arrays[j];
- PoolVector<int> src = a[j];
+ Vector<int> dst = arrays[j];
+ Vector<int> src = a[j];
if (dst.size() == 0 || src.size() == 0) {
arrays[j] = Variant();
continue;
}
{
int ss = src.size();
- PoolVector<int>::Write w = src.write();
+ int *w = src.ptrw();
for (int k = 0; k < ss; k++) {
w[k] += index_accum;
}
@@ -372,18 +364,18 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
ERR_FAIL_COND_V(arrays.size() != ARRAY_MAX, Ref<ArrayMesh>());
{
- PoolVector<int>::Write ir;
- PoolVector<int> indices = arrays[ARRAY_INDEX];
+ int *ir = nullptr;
+ Vector<int> indices = arrays[ARRAY_INDEX];
bool has_indices = false;
- PoolVector<Vector3> vertices = arrays[ARRAY_VERTEX];
+ Vector<Vector3> vertices = arrays[ARRAY_VERTEX];
int vc = vertices.size();
ERR_FAIL_COND_V(!vc, Ref<ArrayMesh>());
- PoolVector<Vector3>::Write r = vertices.write();
+ Vector3 *r = vertices.ptrw();
if (indices.size()) {
ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ArrayMesh>());
vc = indices.size();
- ir = indices.write();
+ ir = indices.ptrw();
has_indices = true;
}
@@ -391,7 +383,6 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
//fill normals with triangle normals
for (int i = 0; i < vc; i += 3) {
-
Vector3 t[3];
if (has_indices) {
@@ -407,14 +398,14 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
Vector3 n = Plane(t[0], t[1], t[2]).normal;
for (int j = 0; j < 3; j++) {
-
Map<Vector3, Vector3>::Element *E = normal_accum.find(t[j]);
if (!E) {
normal_accum[t[j]] = n;
} else {
float d = n.dot(E->get());
- if (d < 1.0)
+ if (d < 1.0) {
E->get() += n * (1.0 - d);
+ }
//E->get()+=n;
}
}
@@ -430,7 +421,6 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
int vc2 = vertices.size();
for (int i = 0; i < vc2; i++) {
-
Vector3 t = r[i];
Map<Vector3, Vector3>::Element *E = normal_accum.find(t);
@@ -440,32 +430,25 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
r[i] = t;
}
- r.release();
arrays[ARRAY_VERTEX] = vertices;
if (!has_indices) {
-
- PoolVector<int> new_indices;
+ Vector<int> new_indices;
new_indices.resize(vertices.size());
- PoolVector<int>::Write iw = new_indices.write();
+ int *iw = new_indices.ptrw();
for (int j = 0; j < vc2; j += 3) {
-
iw[j] = j;
iw[j + 1] = j + 2;
iw[j + 2] = j + 1;
}
- iw.release();
arrays[ARRAY_INDEX] = new_indices;
} else {
-
for (int j = 0; j < vc; j += 3) {
-
SWAP(ir[j + 1], ir[j + 2]);
}
- ir.release();
arrays[ARRAY_INDEX] = indices;
}
}
@@ -475,21 +458,20 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
return newmesh;
}
-void Mesh::set_lightmap_size_hint(const Vector2 &p_size) {
+void Mesh::set_lightmap_size_hint(const Size2i &p_size) {
lightmap_size_hint = p_size;
}
-Size2 Mesh::get_lightmap_size_hint() const {
+Size2i Mesh::get_lightmap_size_hint() const {
return lightmap_size_hint;
}
void Mesh::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint);
ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint);
ClassDB::bind_method(D_METHOD("get_aabb"), &Mesh::get_aabb);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count);
ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays);
@@ -500,10 +482,8 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP);
- BIND_ENUM_CONSTANT(PRIMITIVE_LINE_LOOP);
BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES);
BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP);
- BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_FAN);
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED);
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE);
@@ -518,19 +498,14 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BASE);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_VERTEX);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BONES);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_WEIGHTS);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX);
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
- BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_16_BIT_BONES);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
@@ -551,21 +526,14 @@ void Mesh::clear_cache() const {
debug_lines.clear();
}
-Vector<Ref<Shape> > Mesh::convex_decompose() const {
+Vector<Ref<Shape3D>> Mesh::convex_decompose() const {
+ ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape3D>>());
- ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape> >());
-
- PoolVector<Face3> faces = get_faces();
- Vector<Face3> f3;
- f3.resize(faces.size());
- PoolVector<Face3>::Read f = faces.read();
- for (int i = 0; i < f3.size(); i++) {
- f3.write[i] = f[i];
- }
+ const Vector<Face3> faces = get_faces();
- Vector<Vector<Face3> > decomposed = convex_composition_function(f3);
+ Vector<Vector<Face3>> decomposed = convex_composition_function(faces);
- Vector<Ref<Shape> > ret;
+ Vector<Ref<Shape3D>> ret;
for (int i = 0; i < decomposed.size(); i++) {
Set<Vector3> points;
@@ -575,17 +543,17 @@ Vector<Ref<Shape> > Mesh::convex_decompose() const {
points.insert(decomposed[i][j].vertex[2]);
}
- PoolVector<Vector3> convex_points;
+ Vector<Vector3> convex_points;
convex_points.resize(points.size());
{
- PoolVector<Vector3>::Write w = convex_points.write();
+ Vector3 *w = convex_points.ptrw();
int idx = 0;
for (Set<Vector3>::Element *E = points.front(); E; E = E->next()) {
w[idx++] = E->get();
}
}
- Ref<ConvexPolygonShape> shape;
+ Ref<ConvexPolygonShape3D> shape;
shape.instance();
shape->set_points(convex_points);
ret.push_back(shape);
@@ -597,86 +565,225 @@ Vector<Ref<Shape> > Mesh::convex_decompose() const {
Mesh::Mesh() {
}
-bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
+static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) {
+ bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE)));
+ bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES);
+ bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2));
+ bool weight_32 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_TEX_UV2 << 2));
+
+ print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32));
+
+ if (!vertex_16bit && !bone_8 && !weight_32) {
+ return p_src;
+ }
+
+ bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1));
+
+ uint32_t src_stride = p_src.size() / p_elements;
+ uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0);
+
+ Vector<uint8_t> ret = p_src;
+
+ ret.resize(dst_stride * p_elements);
+ {
+ uint8_t *w = ret.ptrw();
+ const uint8_t *r = p_src.ptr();
+
+ for (uint32_t i = 0; i < p_elements; i++) {
+ uint32_t remaining = src_stride;
+ const uint8_t *src = (const uint8_t *)(r + src_stride * i);
+ uint8_t *dst = (uint8_t *)(w + dst_stride * i);
+
+ if (!vertex_2d) { //3D
+ if (vertex_16bit) {
+ float *dstw = (float *)dst;
+ const uint16_t *srcr = (const uint16_t *)src;
+ dstw[0] = Math::half_to_float(srcr[0]);
+ dstw[1] = Math::half_to_float(srcr[1]);
+ dstw[2] = Math::half_to_float(srcr[2]);
+ remaining -= 8;
+ src += 8;
+ } else {
+ src += 12;
+ remaining -= 12;
+ }
+ dst += 12;
+ } else {
+ if (vertex_16bit) {
+ float *dstw = (float *)dst;
+ const uint16_t *srcr = (const uint16_t *)src;
+ dstw[0] = Math::half_to_float(srcr[0]);
+ dstw[1] = Math::half_to_float(srcr[1]);
+ remaining -= 4;
+ src += 4;
+ } else {
+ src += 8;
+ remaining -= 8;
+ }
+ dst += 8;
+ }
+
+ if (has_bones) {
+ remaining -= bone_8 ? 4 : 8;
+ remaining -= weight_32 ? 16 : 8;
+ }
+
+ for (uint32_t j = 0; j < remaining; j++) {
+ dst[j] = src[j];
+ }
+
+ if (has_bones) {
+ dst += remaining;
+ src += remaining;
+
+ if (bone_8) {
+ const uint8_t *src_bones = (const uint8_t *)src;
+ uint16_t *dst_bones = (uint16_t *)dst;
+
+ dst_bones[0] = src_bones[0];
+ dst_bones[1] = src_bones[1];
+ dst_bones[2] = src_bones[2];
+ dst_bones[3] = src_bones[3];
+
+ src += 4;
+ } else {
+ for (uint32_t j = 0; j < 8; j++) {
+ dst[j] = src[j];
+ }
+ src += 8;
+ }
+
+ dst += 8;
+
+ if (weight_32) {
+ const float *src_weights = (const float *)src;
+ uint16_t *dst_weights = (uint16_t *)dst;
+
+ dst_weights[0] = CLAMP(src_weights[0] * 65535, 0, 65535); //16bits unorm
+ dst_weights[1] = CLAMP(src_weights[1] * 65535, 0, 65535);
+ dst_weights[2] = CLAMP(src_weights[2] * 65535, 0, 65535);
+ dst_weights[3] = CLAMP(src_weights[3] * 65535, 0, 65535);
+
+ } else {
+ for (uint32_t j = 0; j < 8; j++) {
+ dst[j] = src[j];
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
String sname = p_name;
if (p_name == "blend_shape/names") {
-
- PoolVector<String> sk = p_value;
+ Vector<String> sk = p_value;
int sz = sk.size();
- PoolVector<String>::Read r = sk.read();
- for (int i = 0; i < sz; i++)
+ const String *r = sk.ptr();
+ for (int i = 0; i < sz; i++) {
add_blend_shape(r[i]);
+ }
return true;
}
if (p_name == "blend_shape/mode") {
-
set_blend_shape_mode(BlendShapeMode(int(p_value)));
return true;
}
if (sname.begins_with("surface_")) {
-
int sl = sname.find("/");
- if (sl == -1)
+ if (sl == -1) {
return false;
+ }
int idx = sname.substr(8, sl - 8).to_int() - 1;
String what = sname.get_slicec('/', 1);
- if (what == "material")
+ if (what == "material") {
surface_set_material(idx, p_value);
- else if (what == "name")
+ } else if (what == "name") {
surface_set_name(idx, p_value);
+ }
return true;
}
- if (!sname.begins_with("surfaces"))
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
+ if (!sname.begins_with("surfaces")) {
return false;
+ }
+
+ WARN_DEPRECATED_MSG("Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene.");
int idx = sname.get_slicec('/', 1).to_int();
String what = sname.get_slicec('/', 2);
if (idx == surfaces.size()) {
-
//create
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("primitive"), false);
if (d.has("arrays")) {
- //old format
+ //oldest format (2.x)
ERR_FAIL_COND_V(!d.has("morph_arrays"), false);
add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]);
} else if (d.has("array_data")) {
-
- PoolVector<uint8_t> array_data = d["array_data"];
- PoolVector<uint8_t> array_index_data;
- if (d.has("array_index_data"))
+ //print_line("array data (old style");
+ //older format (3.x)
+ Vector<uint8_t> array_data = d["array_data"];
+ Vector<uint8_t> array_index_data;
+ if (d.has("array_index_data")) {
array_index_data = d["array_index_data"];
+ }
ERR_FAIL_COND_V(!d.has("format"), false);
uint32_t format = d["format"];
uint32_t primitive = d["primitive"];
+ uint32_t primitive_remap[7] = {
+ PRIMITIVE_POINTS,
+ PRIMITIVE_LINES,
+ PRIMITIVE_LINE_STRIP,
+ PRIMITIVE_LINES,
+ PRIMITIVE_TRIANGLES,
+ PRIMITIVE_TRIANGLE_STRIP,
+ PRIMITIVE_TRIANGLE_STRIP
+ };
+
+ primitive = primitive_remap[primitive]; //compatibility
+
ERR_FAIL_COND_V(!d.has("vertex_count"), false);
int vertex_count = d["vertex_count"];
+ array_data = _fix_array_compatibility(array_data, format, vertex_count);
+
int index_count = 0;
- if (d.has("index_count"))
+ if (d.has("index_count")) {
index_count = d["index_count"];
+ }
- Vector<PoolVector<uint8_t> > blend_shapes;
+ Vector<Vector<uint8_t>> blend_shapes;
if (d.has("blend_shape_data")) {
Array blend_shape_data = d["blend_shape_data"];
for (int i = 0; i < blend_shape_data.size(); i++) {
- PoolVector<uint8_t> shape = blend_shape_data[i];
+ Vector<uint8_t> shape = blend_shape_data[i];
+ shape = _fix_array_compatibility(shape, format, vertex_count);
+
blend_shapes.push_back(shape);
}
}
+ //clear unused flags
+ print_line("format pre: " + itos(format));
+ format &= ~uint32_t((1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE)) | (ARRAY_COMPRESS_INDEX << 2) | (ARRAY_COMPRESS_TEX_UV2 << 2));
+ print_line("format post: " + itos(format));
+
ERR_FAIL_COND_V(!d.has("aabb"), false);
AABB aabb = d["aabb"];
@@ -696,7 +803,6 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
}
if (d.has("material")) {
-
surface_set_material(idx, d["material"]);
}
if (d.has("name")) {
@@ -705,276 +811,412 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
+#endif // DISABLE_DEPRECATED
return false;
}
-bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
+Array ArrayMesh::_get_surfaces() const {
+ if (mesh.is_null()) {
+ return Array();
+ }
+
+ Array ret;
+ for (int i = 0; i < surfaces.size(); i++) {
+ RenderingServer::SurfaceData surface = RS::get_singleton()->mesh_get_surface(mesh, i);
+ Dictionary data;
+ data["format"] = surface.format;
+ data["primitive"] = surface.primitive;
+ data["vertex_data"] = surface.vertex_data;
+ data["vertex_count"] = surface.vertex_count;
+ data["aabb"] = surface.aabb;
+ if (surface.index_count) {
+ data["index_data"] = surface.index_data;
+ data["index_count"] = surface.index_count;
+ };
+
+ Array lods;
+ for (int j = 0; j < surface.lods.size(); j++) {
+ lods.push_back(surface.lods[j].edge_length);
+ lods.push_back(surface.lods[j].index_data);
+ }
+
+ if (lods.size()) {
+ data["lods"] = lods;
+ }
+
+ Array bone_aabbs;
+ for (int j = 0; j < surface.bone_aabbs.size(); j++) {
+ bone_aabbs.push_back(surface.bone_aabbs[j]);
+ }
+ if (bone_aabbs.size()) {
+ data["bone_aabbs"] = bone_aabbs;
+ }
+
+ Array blend_shapes;
+ for (int j = 0; j < surface.blend_shapes.size(); j++) {
+ blend_shapes.push_back(surface.blend_shapes[j]);
+ }
+
+ if (surfaces[i].material.is_valid()) {
+ data["material"] = surfaces[i].material;
+ }
+
+ if (surfaces[i].name != String()) {
+ data["name"] = surfaces[i].name;
+ }
+
+ if (surfaces[i].is_2d) {
+ data["2d"] = true;
+ }
+
+ ret.push_back(data);
+ }
+ print_line("Saving surfaces: " + itos(ret.size()));
+
+ return ret;
+}
+
+void ArrayMesh::_create_if_empty() const {
+ if (!mesh.is_valid()) {
+ mesh = RS::get_singleton()->mesh_create();
+ RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode);
+ }
+}
+
+void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
+ Vector<RS::SurfaceData> surface_data;
+ Vector<Ref<Material>> surface_materials;
+ Vector<String> surface_names;
+ Vector<bool> surface_2d;
+
+ for (int i = 0; i < p_surfaces.size(); i++) {
+ RS::SurfaceData surface;
+ Dictionary d = p_surfaces[i];
+ ERR_FAIL_COND(!d.has("format"));
+ ERR_FAIL_COND(!d.has("primitive"));
+ ERR_FAIL_COND(!d.has("vertex_data"));
+ ERR_FAIL_COND(!d.has("vertex_count"));
+ ERR_FAIL_COND(!d.has("aabb"));
+ surface.format = d["format"];
+ surface.primitive = RS::PrimitiveType(int(d["primitive"]));
+ surface.vertex_data = d["vertex_data"];
+ surface.vertex_count = d["vertex_count"];
+ surface.aabb = d["aabb"];
+
+ if (d.has("index_data")) {
+ ERR_FAIL_COND(!d.has("index_count"));
+ surface.index_data = d["index_data"];
+ surface.index_count = d["index_count"];
+ }
+
+ if (d.has("lods")) {
+ Array lods = d["lods"];
+ ERR_FAIL_COND(lods.size() & 1); //must be even
+ for (int j = 0; j < lods.size(); j += 2) {
+ RS::SurfaceData::LOD lod;
+ lod.edge_length = lods[j + 0];
+ lod.index_data = lods[j + 1];
+ surface.lods.push_back(lod);
+ }
+ }
+
+ if (d.has("bone_aabbs")) {
+ Array bone_aabbs = d["bone_aabbs"];
+ for (int j = 0; j < bone_aabbs.size(); j++) {
+ surface.bone_aabbs.push_back(bone_aabbs[j]);
+ }
+ }
+
+ if (d.has("blend_shapes")) {
+ Array blend_shapes;
+ for (int j = 0; j < blend_shapes.size(); j++) {
+ surface.blend_shapes.push_back(blend_shapes[j]);
+ }
+ }
+
+ Ref<Material> material;
+ if (d.has("material")) {
+ material = d["material"];
+ if (material.is_valid()) {
+ surface.material = material->get_rid();
+ }
+ }
+
+ String name;
+ if (d.has("name")) {
+ name = d["name"];
+ }
+
+ bool _2d = false;
+ if (d.has("2d")) {
+ _2d = d["2d"];
+ }
+ /*
+ print_line("format: " + itos(surface.format));
+ print_line("aabb: " + surface.aabb);
+ print_line("array size: " + itos(surface.vertex_data.size()));
+ print_line("vertex count: " + itos(surface.vertex_count));
+ print_line("index size: " + itos(surface.index_data.size()));
+ print_line("index count: " + itos(surface.index_count));
+ print_line("primitive: " + itos(surface.primitive));
+*/
+ surface_data.push_back(surface);
+ surface_materials.push_back(material);
+ surface_names.push_back(name);
+ surface_2d.push_back(_2d);
+ }
+
+ if (mesh.is_valid()) {
+ //if mesh exists, it needs to be updated
+ RS::get_singleton()->mesh_clear(mesh);
+ for (int i = 0; i < surface_data.size(); i++) {
+ RS::get_singleton()->mesh_add_surface(mesh, surface_data[i]);
+ }
+ } else {
+ // if mesh does not exist (first time this is loaded, most likely),
+ // we can create it with a single call, which is a lot more efficient and thread friendly
+ mesh = RS::get_singleton()->mesh_create_from_surfaces(surface_data);
+ RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode);
+ }
+
+ surfaces.clear();
+
+ aabb = AABB();
+ for (int i = 0; i < surface_data.size(); i++) {
+ Surface s;
+ s.aabb = surface_data[i].aabb;
+ if (i == 0) {
+ aabb = s.aabb;
+ blend_shapes.resize(surface_data[i].blend_shapes.size());
+ } else {
+ aabb.merge_with(s.aabb);
+ }
+
+ s.material = surface_materials[i];
+ s.is_2d = surface_2d[i];
+ s.name = surface_names[i];
+
+ s.format = surface_data[i].format;
+ s.primitive = PrimitiveType(surface_data[i].primitive);
+ s.array_length = surface_data[i].vertex_count;
+ s.index_array_length = surface_data[i].index_count;
- if (_is_generated())
+ surfaces.push_back(s);
+ }
+}
+
+bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
+ if (_is_generated()) {
return false;
+ }
String sname = p_name;
if (p_name == "blend_shape/names") {
-
- PoolVector<String> sk;
- for (int i = 0; i < blend_shapes.size(); i++)
+ Vector<String> sk;
+ for (int i = 0; i < blend_shapes.size(); i++) {
sk.push_back(blend_shapes[i]);
+ }
r_ret = sk;
return true;
} else if (p_name == "blend_shape/mode") {
-
r_ret = get_blend_shape_mode();
return true;
} else if (sname.begins_with("surface_")) {
-
int sl = sname.find("/");
- if (sl == -1)
+ if (sl == -1) {
return false;
+ }
int idx = sname.substr(8, sl - 8).to_int() - 1;
String what = sname.get_slicec('/', 1);
- if (what == "material")
+ if (what == "material") {
r_ret = surface_get_material(idx);
- else if (what == "name")
+ } else if (what == "name") {
r_ret = surface_get_name(idx);
+ }
return true;
- } else if (!sname.begins_with("surfaces"))
- return false;
-
- int idx = sname.get_slicec('/', 1).to_int();
- ERR_FAIL_INDEX_V(idx, surfaces.size(), false);
-
- Dictionary d;
-
- d["array_data"] = VS::get_singleton()->mesh_surface_get_array(mesh, idx);
- d["vertex_count"] = VS::get_singleton()->mesh_surface_get_array_len(mesh, idx);
- d["array_index_data"] = VS::get_singleton()->mesh_surface_get_index_array(mesh, idx);
- d["index_count"] = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, idx);
- d["primitive"] = VS::get_singleton()->mesh_surface_get_primitive_type(mesh, idx);
- d["format"] = VS::get_singleton()->mesh_surface_get_format(mesh, idx);
- d["aabb"] = VS::get_singleton()->mesh_surface_get_aabb(mesh, idx);
-
- Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx);
- Array arr;
- arr.resize(skel_aabb.size());
- for (int i = 0; i < skel_aabb.size(); i++) {
- arr[i] = skel_aabb[i];
}
- d["skeleton_aabb"] = arr;
-
- Vector<PoolVector<uint8_t> > blend_shape_data = VS::get_singleton()->mesh_surface_get_blend_shapes(mesh, idx);
-
- Array md;
- for (int i = 0; i < blend_shape_data.size(); i++) {
- md.push_back(blend_shape_data[i]);
- }
-
- d["blend_shape_data"] = md;
-
- Ref<Material> m = surface_get_material(idx);
- if (m.is_valid())
- d["material"] = m;
- String n = surface_get_name(idx);
- if (n != "")
- d["name"] = n;
-
- r_ret = d;
return true;
}
void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
-
- if (_is_generated())
+ if (_is_generated()) {
return;
+ }
if (blend_shapes.size()) {
- p_list->push_back(PropertyInfo(Variant::POOL_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::PACKED_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::INT, "blend_shape/mode", PROPERTY_HINT_ENUM, "Normalized,Relative"));
}
for (int i = 0; i < surfaces.size(); i++) {
-
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "surfaces/" + itos(i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
if (surfaces[i].is_2d) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial", PROPERTY_USAGE_EDITOR));
} else {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_EDITOR));
}
}
}
void ArrayMesh::_recompute_aabb() {
-
// regenerate AABB
aabb = AABB();
for (int i = 0; i < surfaces.size(); i++) {
-
- if (i == 0)
+ if (i == 0) {
aabb = surfaces[i].aabb;
- else
+ } else {
aabb.merge_with(surfaces[i].aabb);
+ }
}
}
-
-void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) {
+#ifndef _MSC_VER
+#warning need to add binding to add_surface using future MeshSurfaceData object
+#endif
+void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<RS::SurfaceData::LOD> &p_lods) {
+ _create_if_empty();
Surface s;
s.aabb = p_aabb;
s.is_2d = p_format & ARRAY_FLAG_USE_2D_VERTICES;
+ s.primitive = p_primitive;
+ s.array_length = p_vertex_count;
+ s.index_array_length = p_index_count;
+ s.format = p_format;
+
surfaces.push_back(s);
_recompute_aabb();
- VisualServer::get_singleton()->mesh_add_surface(mesh, p_format, (VS::PrimitiveType)p_primitive, p_array, p_vertex_count, p_index_array, p_index_count, p_aabb, p_blend_shapes, p_bone_aabbs);
-}
-
-void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_flags) {
-
- ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
-
- Surface s;
-
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_flags);
+ RS::SurfaceData sd;
+ sd.format = p_format;
+ sd.primitive = RS::PrimitiveType(p_primitive);
+ sd.aabb = p_aabb;
+ sd.vertex_count = p_vertex_count;
+ sd.vertex_data = p_array;
+ sd.index_count = p_index_count;
+ sd.index_data = p_index_array;
+ sd.blend_shapes = p_blend_shapes;
+ sd.bone_aabbs = p_bone_aabb;
+ sd.lods = p_lods;
- /* make aABB? */ {
+ RenderingServer::get_singleton()->mesh_add_surface(mesh, sd);
- Variant arr = p_arrays[ARRAY_VERTEX];
- PoolVector<Vector3> vertices = arr;
- int len = vertices.size();
- ERR_FAIL_COND(len == 0);
- PoolVector<Vector3>::Read r = vertices.read();
- const Vector3 *vtx = r.ptr();
-
- // check AABB
- AABB aabb;
- for (int i = 0; i < len; i++) {
+ clear_cache();
+ _change_notify();
+ emit_changed();
+}
- if (i == 0)
- aabb.position = vtx[i];
- else
- aabb.expand_to(vtx[i]);
- }
+void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) {
+ ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
- s.aabb = aabb;
- s.is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY;
- surfaces.push_back(s);
+ RS::SurfaceData surface;
- _recompute_aabb();
- }
+ Error err = RS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (RenderingServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_lods, p_flags);
+ ERR_FAIL_COND(err != OK);
- clear_cache();
- _change_notify();
- emit_changed();
+ /* print_line("format: " + itos(surface.format));
+ print_line("aabb: " + surface.aabb);
+ print_line("array size: " + itos(surface.vertex_data.size()));
+ print_line("vertex count: " + itos(surface.vertex_count));
+ print_line("index size: " + itos(surface.index_data.size()));
+ print_line("index count: " + itos(surface.index_count));
+ print_line("primitive: " + itos(surface.primitive));
+*/
+ add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shapes, surface.bone_aabbs, surface.lods);
}
Array ArrayMesh::surface_get_arrays(int p_surface) const {
-
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
- return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
+ return RenderingServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
}
-Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const {
+Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
- return VisualServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface);
+ return RenderingServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface);
}
-int ArrayMesh::get_surface_count() const {
+Dictionary ArrayMesh::surface_get_lods(int p_surface) const {
+ ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Dictionary());
+ return RenderingServer::get_singleton()->mesh_surface_get_lods(mesh, p_surface);
+}
+int ArrayMesh::get_surface_count() const {
return surfaces.size();
}
void ArrayMesh::add_blend_shape(const StringName &p_name) {
-
ERR_FAIL_COND_MSG(surfaces.size(), "Can't add a shape key count if surfaces are already created.");
StringName name = p_name;
if (blend_shapes.find(name) != -1) {
-
int count = 2;
do {
-
name = String(p_name) + " " + itos(count);
count++;
} while (blend_shapes.find(name) != -1);
}
blend_shapes.push_back(name);
- VS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
+ //RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
}
int ArrayMesh::get_blend_shape_count() const {
-
return blend_shapes.size();
}
+
StringName ArrayMesh::get_blend_shape_name(int p_index) const {
ERR_FAIL_INDEX_V(p_index, blend_shapes.size(), StringName());
return blend_shapes[p_index];
}
-void ArrayMesh::clear_blend_shapes() {
+void ArrayMesh::clear_blend_shapes() {
ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created.");
blend_shapes.clear();
}
void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) {
-
blend_shape_mode = p_mode;
- VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)p_mode);
+ if (mesh.is_valid()) {
+ RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)p_mode);
+ }
}
ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const {
-
return blend_shape_mode;
}
-void ArrayMesh::surface_remove(int p_idx) {
-
- ERR_FAIL_INDEX(p_idx, surfaces.size());
- VisualServer::get_singleton()->mesh_remove_surface(mesh, p_idx);
- surfaces.remove(p_idx);
-
- clear_cache();
- _recompute_aabb();
- _change_notify();
- emit_changed();
-}
-
int ArrayMesh::surface_get_array_len(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
- return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, p_idx);
+ return surfaces[p_idx].array_length;
}
int ArrayMesh::surface_get_array_index_len(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
- return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, p_idx);
+ return surfaces[p_idx].index_array_length;
}
uint32_t ArrayMesh::surface_get_format(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0);
- return VisualServer::get_singleton()->mesh_surface_get_format(mesh, p_idx);
+ return surfaces[p_idx].format;
}
ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES);
- return (PrimitiveType)VisualServer::get_singleton()->mesh_surface_get_primitive_type(mesh, p_idx);
+ return surfaces[p_idx].primitive;
}
void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
-
ERR_FAIL_INDEX(p_idx, surfaces.size());
- if (surfaces[p_idx].material == p_material)
+ if (surfaces[p_idx].material == p_material) {
return;
+ }
surfaces.write[p_idx].material = p_material;
- VisualServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid());
+ RenderingServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid());
_change_notify("material");
emit_changed();
@@ -986,12 +1228,10 @@ int ArrayMesh::surface_find_by_name(const String &p_name) const {
return i;
}
}
-
return -1;
}
void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
-
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces.write[p_idx].name = p_name;
@@ -999,20 +1239,17 @@ void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
}
String ArrayMesh::surface_get_name(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), String());
return surfaces[p_idx].name;
}
-void ArrayMesh::surface_update_region(int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) {
-
+void ArrayMesh::surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
ERR_FAIL_INDEX(p_surface, surfaces.size());
- VS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data);
+ RS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data);
emit_changed();
}
void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
-
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces.write[p_idx].aabb = p_aabb;
// set custom aabb too?
@@ -1020,85 +1257,62 @@ void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
}
Ref<Material> ArrayMesh::surface_get_material(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), Ref<Material>());
return surfaces[p_idx].material;
}
-void ArrayMesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) {
-
- VisualServer::get_singleton()->mesh_add_surface_from_mesh_data(mesh, p_mesh_data);
- AABB aabb;
- for (int i = 0; i < p_mesh_data.vertices.size(); i++) {
-
- if (i == 0)
- aabb.position = p_mesh_data.vertices[i];
- else
- aabb.expand_to(p_mesh_data.vertices[i]);
- }
-
- Surface s;
- s.aabb = aabb;
- if (surfaces.size() == 0)
- aabb = s.aabb;
- else
- aabb.merge_with(s.aabb);
-
- clear_cache();
-
- surfaces.push_back(s);
- _change_notify();
-
- emit_changed();
-}
-
RID ArrayMesh::get_rid() const {
-
+ _create_if_empty();
return mesh;
}
-AABB ArrayMesh::get_aabb() const {
+AABB ArrayMesh::get_aabb() const {
return aabb;
}
-void ArrayMesh::set_custom_aabb(const AABB &p_custom) {
+void ArrayMesh::clear_surfaces() {
+ if (!mesh.is_valid()) {
+ return;
+ }
+ RS::get_singleton()->mesh_clear(mesh);
+ surfaces.clear();
+ aabb = AABB();
+}
+void ArrayMesh::set_custom_aabb(const AABB &p_custom) {
+ _create_if_empty();
custom_aabb = p_custom;
- VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
+ RS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
emit_changed();
}
AABB ArrayMesh::get_custom_aabb() const {
-
return custom_aabb;
}
void ArrayMesh::regen_normalmaps() {
-
- Vector<Ref<SurfaceTool> > surfs;
+ if (surfaces.size() == 0) {
+ return;
+ }
+ Vector<Ref<SurfaceTool>> surfs;
for (int i = 0; i < get_surface_count(); i++) {
-
Ref<SurfaceTool> st = memnew(SurfaceTool);
st->create_from(Ref<ArrayMesh>(this), i);
surfs.push_back(st);
}
- while (get_surface_count()) {
- surface_remove(0);
- }
+ clear_surfaces();
for (int i = 0; i < surfs.size(); i++) {
-
surfs.write[i]->generate_tangents();
surfs.write[i]->commit(Ref<ArrayMesh>(this));
}
}
//dirty hack
-bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = NULL;
+bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache);
struct ArrayMeshLightmapSurface {
-
Ref<Material> material;
Vector<SurfaceTool::Vertex> vertices;
Mesh::PrimitiveType primitive;
@@ -1106,18 +1320,31 @@ struct ArrayMeshLightmapSurface {
};
Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {
+ int *cache_data = nullptr;
+ unsigned int cache_size = 0;
+ bool use_cache = false; // Don't use cache
+ return lightmap_unwrap_cached(cache_data, cache_size, use_cache, p_base_transform, p_texel_size);
+}
+Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform, float p_texel_size) {
ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes.");
Vector<float> vertices;
Vector<float> normals;
Vector<int> indices;
- Vector<int> face_materials;
Vector<float> uv;
- Vector<Pair<int, int> > uv_index;
+ Vector<Pair<int, int>> uv_indices;
+
+ Vector<ArrayMeshLightmapSurface> lightmap_surfaces;
+
+ // Keep only the scale
+ Transform transform = p_base_transform;
+ transform.origin = Vector3();
+ transform.looking_at(Vector3(1, 0, 0), Vector3(0, 1, 0));
+
+ Basis normal_basis = transform.basis.inverse().transposed();
- Vector<ArrayMeshLightmapSurface> surfaces;
for (int i = 0; i < get_surface_count(); i++) {
ArrayMeshLightmapSurface s;
s.primitive = surface_get_primitive_type(i);
@@ -1130,23 +1357,22 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
s.material = surface_get_material(i);
s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays);
- PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX];
+ Vector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX];
int vc = rvertices.size();
- PoolVector<Vector3>::Read r = rvertices.read();
+ const Vector3 *r = rvertices.ptr();
- PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL];
- PoolVector<Vector3>::Read rn = rnormals.read();
+ Vector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL];
+ const Vector3 *rn = rnormals.ptr();
int vertex_ofs = vertices.size() / 3;
vertices.resize((vertex_ofs + vc) * 3);
normals.resize((vertex_ofs + vc) * 3);
- uv_index.resize(vertex_ofs + vc);
+ uv_indices.resize(vertex_ofs + vc);
for (int j = 0; j < vc; j++) {
-
- Vector3 v = p_base_transform.xform(r[j]);
- Vector3 n = p_base_transform.basis.xform(rn[j]).normalized();
+ Vector3 v = transform.xform(r[j]);
+ Vector3 n = normal_basis.xform(rn[j]).normalized();
vertices.write[(j + vertex_ofs) * 3 + 0] = v.x;
vertices.write[(j + vertex_ofs) * 3 + 1] = v.y;
@@ -1154,38 +1380,37 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
normals.write[(j + vertex_ofs) * 3 + 0] = n.x;
normals.write[(j + vertex_ofs) * 3 + 1] = n.y;
normals.write[(j + vertex_ofs) * 3 + 2] = n.z;
- uv_index.write[j + vertex_ofs] = Pair<int, int>(i, j);
+ uv_indices.write[j + vertex_ofs] = Pair<int, int>(i, j);
}
- PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX];
+ Vector<int> rindices = arrays[Mesh::ARRAY_INDEX];
int ic = rindices.size();
if (ic == 0) {
-
for (int j = 0; j < vc / 3; j++) {
- if (Face3(r[j * 3 + 0], r[j * 3 + 1], r[j * 3 + 2]).is_degenerate())
+ if (Face3(r[j * 3 + 0], r[j * 3 + 1], r[j * 3 + 2]).is_degenerate()) {
continue;
+ }
indices.push_back(vertex_ofs + j * 3 + 0);
indices.push_back(vertex_ofs + j * 3 + 1);
indices.push_back(vertex_ofs + j * 3 + 2);
- face_materials.push_back(i);
}
} else {
- PoolVector<int>::Read ri = rindices.read();
+ const int *ri = rindices.ptr();
for (int j = 0; j < ic / 3; j++) {
- if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate())
+ if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate()) {
continue;
+ }
indices.push_back(vertex_ofs + ri[j * 3 + 0]);
indices.push_back(vertex_ofs + ri[j * 3 + 1]);
indices.push_back(vertex_ofs + ri[j * 3 + 2]);
- face_materials.push_back(i);
}
}
- surfaces.push_back(s);
+ lightmap_surfaces.push_back(s);
}
//unwrap
@@ -1198,63 +1423,59 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
int size_x;
int size_y;
- bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);
+ bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y, r_cache_data, r_cache_size, r_used_cache);
if (!ok) {
return ERR_CANT_CREATE;
}
//remove surfaces
- while (get_surface_count()) {
- surface_remove(0);
- }
+ clear_surfaces();
//create surfacetools for each surface..
- Vector<Ref<SurfaceTool> > surfaces_tools;
+ Vector<Ref<SurfaceTool>> surfaces_tools;
- for (int i = 0; i < surfaces.size(); i++) {
+ for (int i = 0; i < lightmap_surfaces.size(); i++) {
Ref<SurfaceTool> st;
st.instance();
st->begin(Mesh::PRIMITIVE_TRIANGLES);
- st->set_material(surfaces[i].material);
+ st->set_material(lightmap_surfaces[i].material);
surfaces_tools.push_back(st); //stay there
}
print_verbose("Mesh: Gen indices: " + itos(gen_index_count));
//go through all indices
for (int i = 0; i < gen_index_count; i += 3) {
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_indices.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_indices.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_indices.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG);
-
- ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
+ ERR_FAIL_COND_V(uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 1]]].first || uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
- int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first;
+ int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first;
for (int j = 0; j < 3; j++) {
+ SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second];
- SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second];
-
- if (surfaces[surface].format & ARRAY_FORMAT_COLOR) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) {
surfaces_tools.write[surface]->add_color(v.color);
}
- if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
surfaces_tools.write[surface]->add_uv(v.uv);
}
- if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
surfaces_tools.write[surface]->add_normal(v.normal);
}
- if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
Plane t;
t.normal = v.tangent;
t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
surfaces_tools.write[surface]->add_tangent(t);
}
- if (surfaces[surface].format & ARRAY_FORMAT_BONES) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) {
surfaces_tools.write[surface]->add_bones(v.bones);
}
- if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
surfaces_tools.write[surface]->add_weights(v.weights);
}
@@ -1265,25 +1486,26 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
}
}
- //free stuff
- ::free(gen_vertices);
- ::free(gen_indices);
- ::free(gen_uvs);
-
//generate surfaces
for (int i = 0; i < surfaces_tools.size(); i++) {
surfaces_tools.write[i]->index();
- surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
+ surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), lightmap_surfaces[i].format);
}
set_lightmap_size_hint(Size2(size_x, size_y));
+ if (!r_used_cache) {
+ //free stuff
+ ::free(gen_vertices);
+ ::free(gen_indices);
+ ::free(gen_uvs);
+ }
+
return OK;
}
void ArrayMesh::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count);
ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name);
@@ -1291,8 +1513,8 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
- ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
- ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove);
+ ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces);
ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region);
ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len);
ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len);
@@ -1314,7 +1536,11 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb);
ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative", PROPERTY_USAGE_NOEDITOR), "set_blend_shape_mode", "get_blend_shape_mode");
+ ClassDB::bind_method(D_METHOD("_set_surfaces", "surfaces"), &ArrayMesh::_set_surfaces);
+ ClassDB::bind_method(D_METHOD("_get_surfaces"), &ArrayMesh::_get_surfaces);
+
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
BIND_CONSTANT(NO_INDEX_ARRAY);
@@ -1343,7 +1569,7 @@ void ArrayMesh::_bind_methods() {
}
void ArrayMesh::reload_from_file() {
- VisualServer::get_singleton()->mesh_clear(mesh);
+ RenderingServer::get_singleton()->mesh_clear(mesh);
surfaces.clear();
clear_blend_shapes();
clear_cache();
@@ -1354,12 +1580,13 @@ void ArrayMesh::reload_from_file() {
}
ArrayMesh::ArrayMesh() {
-
- mesh = VisualServer::get_singleton()->mesh_create();
+ //mesh is now created on demand
+ //mesh = RenderingServer::get_singleton()->mesh_create();
blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
}
ArrayMesh::~ArrayMesh() {
-
- VisualServer::get_singleton()->free(mesh);
+ if (mesh.is_valid()) {
+ RenderingServer::get_singleton()->free(mesh);
+ }
}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 30ce94f16b..b0a30a5627 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -35,15 +35,15 @@
#include "core/math/triangle_mesh.h"
#include "core/resource.h"
#include "scene/resources/material.h"
-#include "scene/resources/shape.h"
-#include "servers/visual_server.h"
+#include "scene/resources/shape_3d.h"
+#include "servers/rendering_server.h"
class Mesh : public Resource {
GDCLASS(Mesh, Resource);
mutable Ref<TriangleMesh> triangle_mesh; //cached
mutable Vector<Vector3> debug_lines;
- Size2 lightmap_size_hint;
+ Size2i lightmap_size_hint;
protected:
static void _bind_methods();
@@ -51,22 +51,22 @@ protected:
public:
enum {
- NO_INDEX_ARRAY = VisualServer::NO_INDEX_ARRAY,
- ARRAY_WEIGHTS_SIZE = VisualServer::ARRAY_WEIGHTS_SIZE
+ NO_INDEX_ARRAY = RenderingServer::NO_INDEX_ARRAY,
+ ARRAY_WEIGHTS_SIZE = RenderingServer::ARRAY_WEIGHTS_SIZE
};
enum ArrayType {
- ARRAY_VERTEX = VisualServer::ARRAY_VERTEX,
- ARRAY_NORMAL = VisualServer::ARRAY_NORMAL,
- ARRAY_TANGENT = VisualServer::ARRAY_TANGENT,
- ARRAY_COLOR = VisualServer::ARRAY_COLOR,
- ARRAY_TEX_UV = VisualServer::ARRAY_TEX_UV,
- ARRAY_TEX_UV2 = VisualServer::ARRAY_TEX_UV2,
- ARRAY_BONES = VisualServer::ARRAY_BONES,
- ARRAY_WEIGHTS = VisualServer::ARRAY_WEIGHTS,
- ARRAY_INDEX = VisualServer::ARRAY_INDEX,
- ARRAY_MAX = VisualServer::ARRAY_MAX
+ ARRAY_VERTEX = RenderingServer::ARRAY_VERTEX,
+ ARRAY_NORMAL = RenderingServer::ARRAY_NORMAL,
+ ARRAY_TANGENT = RenderingServer::ARRAY_TANGENT,
+ ARRAY_COLOR = RenderingServer::ARRAY_COLOR,
+ ARRAY_TEX_UV = RenderingServer::ARRAY_TEX_UV,
+ ARRAY_TEX_UV2 = RenderingServer::ARRAY_TEX_UV2,
+ ARRAY_BONES = RenderingServer::ARRAY_BONES,
+ ARRAY_WEIGHTS = RenderingServer::ARRAY_WEIGHTS,
+ ARRAY_INDEX = RenderingServer::ARRAY_INDEX,
+ ARRAY_MAX = RenderingServer::ARRAY_MAX
};
@@ -83,38 +83,33 @@ public:
ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX,
ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1),
- ARRAY_COMPRESS_VERTEX = 1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE), // mandatory
ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE),
- ARRAY_COMPRESS_BONES = 1 << (ARRAY_BONES + ARRAY_COMPRESS_BASE),
- ARRAY_COMPRESS_WEIGHTS = 1 << (ARRAY_WEIGHTS + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE),
ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1,
- ARRAY_FLAG_USE_16_BIT_BONES = ARRAY_COMPRESS_INDEX << 2,
ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3,
- ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_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
};
enum PrimitiveType {
- PRIMITIVE_POINTS = VisualServer::PRIMITIVE_POINTS,
- PRIMITIVE_LINES = VisualServer::PRIMITIVE_LINES,
- PRIMITIVE_LINE_STRIP = VisualServer::PRIMITIVE_LINE_STRIP,
- PRIMITIVE_LINE_LOOP = VisualServer::PRIMITIVE_LINE_LOOP,
- PRIMITIVE_TRIANGLES = VisualServer::PRIMITIVE_TRIANGLES,
- PRIMITIVE_TRIANGLE_STRIP = VisualServer::PRIMITIVE_TRIANGLE_STRIP,
- PRIMITIVE_TRIANGLE_FAN = VisualServer::PRIMITIVE_TRIANGLE_FAN,
+ PRIMITIVE_POINTS = RenderingServer::PRIMITIVE_POINTS,
+ PRIMITIVE_LINES = RenderingServer::PRIMITIVE_LINES,
+ PRIMITIVE_LINE_STRIP = RenderingServer::PRIMITIVE_LINE_STRIP,
+ PRIMITIVE_TRIANGLES = RenderingServer::PRIMITIVE_TRIANGLES,
+ PRIMITIVE_TRIANGLE_STRIP = RenderingServer::PRIMITIVE_TRIANGLE_STRIP,
+ PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX,
};
enum BlendShapeMode {
- BLEND_SHAPE_MODE_NORMALIZED = VS::BLEND_SHAPE_MODE_NORMALIZED,
- BLEND_SHAPE_MODE_RELATIVE = VS::BLEND_SHAPE_MODE_RELATIVE,
+ BLEND_SHAPE_MODE_NORMALIZED = RS::BLEND_SHAPE_MODE_NORMALIZED,
+ BLEND_SHAPE_MODE_RELATIVE = RS::BLEND_SHAPE_MODE_RELATIVE,
};
virtual int get_surface_count() const = 0;
@@ -123,6 +118,7 @@ public:
virtual bool surface_is_softbody_friendly(int p_idx) const;
virtual Array surface_get_arrays(int p_surface) const = 0;
virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0;
+ virtual Dictionary surface_get_lods(int p_surface) const = 0;
virtual uint32_t surface_get_format(int p_idx) const = 0;
virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0;
virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) = 0;
@@ -130,50 +126,58 @@ public:
virtual int get_blend_shape_count() const = 0;
virtual StringName get_blend_shape_name(int p_index) const = 0;
- PoolVector<Face3> get_faces() const;
+ Vector<Face3> get_faces() const;
Ref<TriangleMesh> generate_triangle_mesh() const;
void generate_debug_mesh_lines(Vector<Vector3> &r_lines);
void generate_debug_mesh_indices(Vector<Vector3> &r_points);
- Ref<Shape> create_trimesh_shape() const;
- Ref<Shape> create_convex_shape() const;
+ Ref<Shape3D> create_trimesh_shape() const;
+ Ref<Shape3D> create_convex_shape() const;
Ref<Mesh> create_outline(float p_margin) const;
virtual AABB get_aabb() const = 0;
- void set_lightmap_size_hint(const Vector2 &p_size);
- Size2 get_lightmap_size_hint() const;
+ void set_lightmap_size_hint(const Size2i &p_size);
+ Size2i get_lightmap_size_hint() const;
void clear_cache() const;
- typedef Vector<Vector<Face3> > (*ConvexDecompositionFunc)(const Vector<Face3> &);
+ typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &);
static ConvexDecompositionFunc convex_composition_function;
- Vector<Ref<Shape> > convex_decompose() const;
+ Vector<Ref<Shape3D>> convex_decompose() const;
Mesh();
};
class ArrayMesh : public Mesh {
-
GDCLASS(ArrayMesh, Mesh);
RES_BASE_EXTENSION("mesh");
+ Array _get_surfaces() const;
+ void _set_surfaces(const Array &p_data);
+
private:
struct Surface {
+ uint32_t format;
+ int array_length;
+ int index_array_length;
+ PrimitiveType primitive;
+
String name;
AABB aabb;
Ref<Material> material;
bool is_2d;
};
Vector<Surface> surfaces;
- RID mesh;
+ mutable RID mesh;
AABB aabb;
BlendShapeMode blend_shape_mode;
Vector<StringName> blend_shapes;
AABB custom_aabb;
+ _FORCE_INLINE_ void _create_if_empty() const;
void _recompute_aabb();
protected:
@@ -186,53 +190,55 @@ protected:
static void _bind_methods();
public:
- void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT);
- void add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>());
+ void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT);
- Array surface_get_arrays(int p_surface) const;
- Array surface_get_blend_shape_arrays(int p_surface) const;
+ void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes = Vector<Vector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>());
+
+ Array surface_get_arrays(int p_surface) const override;
+ Array surface_get_blend_shape_arrays(int p_surface) const override;
+ Dictionary surface_get_lods(int p_surface) const override;
void add_blend_shape(const StringName &p_name);
- int get_blend_shape_count() const;
- StringName get_blend_shape_name(int p_index) const;
+ int get_blend_shape_count() const override;
+ StringName get_blend_shape_name(int p_index) const override;
void clear_blend_shapes();
void set_blend_shape_mode(BlendShapeMode p_mode);
BlendShapeMode get_blend_shape_mode() const;
- void surface_update_region(int p_surface, int p_offset, const PoolVector<uint8_t> &p_data);
+ void surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data);
+
+ int get_surface_count() const override;
- int get_surface_count() const;
- void surface_remove(int p_idx);
+ void clear_surfaces();
void surface_set_custom_aabb(int p_idx, const AABB &p_aabb); //only recognized by driver
- int surface_get_array_len(int p_idx) const;
- int surface_get_array_index_len(int p_idx) const;
- uint32_t surface_get_format(int p_idx) const;
- PrimitiveType surface_get_primitive_type(int p_idx) const;
+ int surface_get_array_len(int p_idx) const override;
+ int surface_get_array_index_len(int p_idx) const override;
+ uint32_t surface_get_format(int p_idx) const override;
+ PrimitiveType surface_get_primitive_type(int p_idx) const override;
bool surface_is_alpha_sorting_enabled(int p_idx) const;
- virtual void surface_set_material(int p_idx, const Ref<Material> &p_material);
- virtual Ref<Material> surface_get_material(int p_idx) const;
+ virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) override;
+ virtual Ref<Material> surface_get_material(int p_idx) const override;
int surface_find_by_name(const String &p_name) const;
void surface_set_name(int p_idx, const String &p_name);
String surface_get_name(int p_idx) const;
- void add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data);
-
void set_custom_aabb(const AABB &p_custom);
AABB get_custom_aabb() const;
- AABB get_aabb() const;
- virtual RID get_rid() const;
+ AABB get_aabb() const override;
+ virtual RID get_rid() const override;
void regen_normalmaps();
Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
+ Error lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
- virtual void reload_from_file();
+ virtual void reload_from_file() override;
ArrayMesh();
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index 7a303443e3..a5c360f123 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -31,7 +31,6 @@
#include "mesh_data_tool.h"
void MeshDataTool::clear() {
-
vertices.clear();
edges.clear();
faces.clear();
@@ -40,14 +39,13 @@ void MeshDataTool::clear() {
}
Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surface) {
-
ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_mesh->surface_get_primitive_type(p_surface) != Mesh::PRIMITIVE_TRIANGLES, ERR_INVALID_PARAMETER);
Array arrays = p_mesh->surface_get_arrays(p_surface);
ERR_FAIL_COND_V(arrays.empty(), ERR_INVALID_PARAMETER);
- PoolVector<Vector3> varray = arrays[Mesh::ARRAY_VERTEX];
+ Vector<Vector3> varray = arrays[Mesh::ARRAY_VERTEX];
int vcount = varray.size();
ERR_FAIL_COND_V(vcount == 0, ERR_INVALID_PARAMETER);
@@ -56,62 +54,71 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
format = p_mesh->surface_get_format(p_surface);
material = p_mesh->surface_get_material(p_surface);
- PoolVector<Vector3>::Read vr = varray.read();
+ const Vector3 *vr = varray.ptr();
- PoolVector<Vector3>::Read nr;
- if (arrays[Mesh::ARRAY_NORMAL].get_type() != Variant::NIL)
- nr = arrays[Mesh::ARRAY_NORMAL].operator PoolVector<Vector3>().read();
+ const Vector3 *nr = nullptr;
+ if (arrays[Mesh::ARRAY_NORMAL].get_type() != Variant::NIL) {
+ nr = arrays[Mesh::ARRAY_NORMAL].operator Vector<Vector3>().ptr();
+ }
- PoolVector<real_t>::Read ta;
- if (arrays[Mesh::ARRAY_TANGENT].get_type() != Variant::NIL)
- ta = arrays[Mesh::ARRAY_TANGENT].operator PoolVector<real_t>().read();
+ const real_t *ta = nullptr;
+ if (arrays[Mesh::ARRAY_TANGENT].get_type() != Variant::NIL) {
+ ta = arrays[Mesh::ARRAY_TANGENT].operator Vector<real_t>().ptr();
+ }
- PoolVector<Vector2>::Read uv;
- if (arrays[Mesh::ARRAY_TEX_UV].get_type() != Variant::NIL)
- uv = arrays[Mesh::ARRAY_TEX_UV].operator PoolVector<Vector2>().read();
- PoolVector<Vector2>::Read uv2;
- if (arrays[Mesh::ARRAY_TEX_UV2].get_type() != Variant::NIL)
- uv2 = arrays[Mesh::ARRAY_TEX_UV2].operator PoolVector<Vector2>().read();
+ const Vector2 *uv = nullptr;
+ if (arrays[Mesh::ARRAY_TEX_UV].get_type() != Variant::NIL) {
+ uv = arrays[Mesh::ARRAY_TEX_UV].operator Vector<Vector2>().ptr();
+ }
+ const Vector2 *uv2 = nullptr;
+ if (arrays[Mesh::ARRAY_TEX_UV2].get_type() != Variant::NIL) {
+ uv2 = arrays[Mesh::ARRAY_TEX_UV2].operator Vector<Vector2>().ptr();
+ }
- PoolVector<Color>::Read col;
- if (arrays[Mesh::ARRAY_COLOR].get_type() != Variant::NIL)
- col = arrays[Mesh::ARRAY_COLOR].operator PoolVector<Color>().read();
+ const Color *col = nullptr;
+ if (arrays[Mesh::ARRAY_COLOR].get_type() != Variant::NIL) {
+ col = arrays[Mesh::ARRAY_COLOR].operator Vector<Color>().ptr();
+ }
- PoolVector<int>::Read bo;
- if (arrays[Mesh::ARRAY_BONES].get_type() != Variant::NIL)
- bo = arrays[Mesh::ARRAY_BONES].operator PoolVector<int>().read();
+ const int *bo = nullptr;
+ if (arrays[Mesh::ARRAY_BONES].get_type() != Variant::NIL) {
+ bo = arrays[Mesh::ARRAY_BONES].operator Vector<int>().ptr();
+ }
- PoolVector<real_t>::Read we;
- if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL)
- we = arrays[Mesh::ARRAY_WEIGHTS].operator PoolVector<real_t>().read();
+ const real_t *we = nullptr;
+ if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL) {
+ we = arrays[Mesh::ARRAY_WEIGHTS].operator Vector<real_t>().ptr();
+ }
vertices.resize(vcount);
for (int i = 0; i < vcount; i++) {
-
Vertex v;
v.vertex = vr[i];
- if (nr.ptr())
+ if (nr) {
v.normal = nr[i];
- if (ta.ptr())
+ }
+ if (ta) {
v.tangent = Plane(ta[i * 4 + 0], ta[i * 4 + 1], ta[i * 4 + 2], ta[i * 4 + 3]);
- if (uv.ptr())
+ }
+ if (uv) {
v.uv = uv[i];
- if (uv2.ptr())
+ }
+ if (uv2) {
v.uv2 = uv2[i];
- if (col.ptr())
+ }
+ if (col) {
v.color = col[i];
+ }
- if (we.ptr()) {
-
+ if (we) {
v.weights.push_back(we[i * 4 + 0]);
v.weights.push_back(we[i * 4 + 1]);
v.weights.push_back(we[i * 4 + 2]);
v.weights.push_back(we[i * 4 + 3]);
}
- if (bo.ptr()) {
-
+ if (bo) {
v.bones.push_back(bo[i * 4 + 0]);
v.bones.push_back(bo[i * 4 + 1]);
v.bones.push_back(bo[i * 4 + 2]);
@@ -121,33 +128,31 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
vertices.write[i] = v;
}
- PoolVector<int> indices;
+ Vector<int> indices;
if (arrays[Mesh::ARRAY_INDEX].get_type() != Variant::NIL) {
-
indices = arrays[Mesh::ARRAY_INDEX];
} else {
//make code simpler
indices.resize(vcount);
- PoolVector<int>::Write iw = indices.write();
- for (int i = 0; i < vcount; i++)
+ int *iw = indices.ptrw();
+ for (int i = 0; i < vcount; i++) {
iw[i] = i;
+ }
}
int icount = indices.size();
- PoolVector<int>::Read r = indices.read();
+ const int *r = indices.ptr();
Map<Point2i, int> edge_indices;
for (int i = 0; i < icount; i += 3) {
-
Vertex *v[3] = { &vertices.write[r[i + 0]], &vertices.write[r[i + 1]], &vertices.write[r[i + 2]] };
int fidx = faces.size();
Face face;
for (int j = 0; j < 3; j++) {
-
face.v[j] = r[i + j];
Point2i edge(r[i + j], r[i + (j + 1) % 3]);
@@ -180,100 +185,99 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
}
Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
-
ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER);
Array arr;
arr.resize(Mesh::ARRAY_MAX);
int vcount = vertices.size();
- PoolVector<Vector3> v;
- PoolVector<Vector3> n;
- PoolVector<real_t> t;
- PoolVector<Vector2> u;
- PoolVector<Vector2> u2;
- PoolVector<Color> c;
- PoolVector<int> b;
- PoolVector<real_t> w;
- PoolVector<int> in;
+ Vector<Vector3> v;
+ Vector<Vector3> n;
+ Vector<real_t> t;
+ Vector<Vector2> u;
+ Vector<Vector2> u2;
+ Vector<Color> c;
+ Vector<int> b;
+ Vector<real_t> w;
+ Vector<int> in;
{
-
v.resize(vcount);
- PoolVector<Vector3>::Write vr = v.write();
+ Vector3 *vr = v.ptrw();
- PoolVector<Vector3>::Write nr;
+ Vector3 *nr = nullptr;
if (format & Mesh::ARRAY_FORMAT_NORMAL) {
n.resize(vcount);
- nr = n.write();
+ nr = n.ptrw();
}
- PoolVector<real_t>::Write ta;
+ real_t *ta = nullptr;
if (format & Mesh::ARRAY_FORMAT_TANGENT) {
t.resize(vcount * 4);
- ta = t.write();
+ ta = t.ptrw();
}
- PoolVector<Vector2>::Write uv;
+ Vector2 *uv = nullptr;
if (format & Mesh::ARRAY_FORMAT_TEX_UV) {
u.resize(vcount);
- uv = u.write();
+ uv = u.ptrw();
}
- PoolVector<Vector2>::Write uv2;
+ Vector2 *uv2 = nullptr;
if (format & Mesh::ARRAY_FORMAT_TEX_UV2) {
u2.resize(vcount);
- uv2 = u2.write();
+ uv2 = u2.ptrw();
}
- PoolVector<Color>::Write col;
+ Color *col = nullptr;
if (format & Mesh::ARRAY_FORMAT_COLOR) {
c.resize(vcount);
- col = c.write();
+ col = c.ptrw();
}
- PoolVector<int>::Write bo;
+ int *bo = nullptr;
if (format & Mesh::ARRAY_FORMAT_BONES) {
b.resize(vcount * 4);
- bo = b.write();
+ bo = b.ptrw();
}
- PoolVector<real_t>::Write we;
+ real_t *we = nullptr;
if (format & Mesh::ARRAY_FORMAT_WEIGHTS) {
w.resize(vcount * 4);
- we = w.write();
+ we = w.ptrw();
}
for (int i = 0; i < vcount; i++) {
-
const Vertex &vtx = vertices[i];
vr[i] = vtx.vertex;
- if (nr.ptr())
+ if (nr) {
nr[i] = vtx.normal;
- if (ta.ptr()) {
+ }
+ if (ta) {
ta[i * 4 + 0] = vtx.tangent.normal.x;
ta[i * 4 + 1] = vtx.tangent.normal.y;
ta[i * 4 + 2] = vtx.tangent.normal.z;
ta[i * 4 + 3] = vtx.tangent.d;
}
- if (uv.ptr())
+ if (uv) {
uv[i] = vtx.uv;
- if (uv2.ptr())
+ }
+ if (uv2) {
uv2[i] = vtx.uv2;
- if (col.ptr())
+ }
+ if (col) {
col[i] = vtx.color;
+ }
- if (we.ptr()) {
-
+ if (we) {
we[i * 4 + 0] = vtx.weights[0];
we[i * 4 + 1] = vtx.weights[1];
we[i * 4 + 2] = vtx.weights[2];
we[i * 4 + 3] = vtx.weights[3];
}
- if (bo.ptr()) {
-
+ if (bo) {
bo[i * 4 + 0] = vtx.bones[0];
bo[i * 4 + 1] = vtx.bones[1];
bo[i * 4 + 2] = vtx.bones[2];
@@ -283,9 +287,8 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
int fc = faces.size();
in.resize(fc * 3);
- PoolVector<int>::Write iw = in.write();
+ int *iw = in.ptrw();
for (int i = 0; i < fc; i++) {
-
iw[i * 3 + 0] = faces[i].v[0];
iw[i * 3 + 1] = faces[i].v[1];
iw[i * 3 + 2] = faces[i].v[2];
@@ -294,20 +297,27 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
arr[Mesh::ARRAY_VERTEX] = v;
arr[Mesh::ARRAY_INDEX] = in;
- if (n.size())
+ if (n.size()) {
arr[Mesh::ARRAY_NORMAL] = n;
- if (c.size())
+ }
+ if (c.size()) {
arr[Mesh::ARRAY_COLOR] = c;
- if (u.size())
+ }
+ if (u.size()) {
arr[Mesh::ARRAY_TEX_UV] = u;
- if (u2.size())
+ }
+ if (u2.size()) {
arr[Mesh::ARRAY_TEX_UV2] = u2;
- if (t.size())
+ }
+ if (t.size()) {
arr[Mesh::ARRAY_TANGENT] = t;
- if (b.size())
+ }
+ if (b.size()) {
arr[Mesh::ARRAY_BONES] = b;
- if (w.size())
+ }
+ if (w.size()) {
arr[Mesh::ARRAY_WEIGHTS] = w;
+ }
Ref<ArrayMesh> ncmesh = p_mesh;
int sc = ncmesh->get_surface_count();
@@ -318,111 +328,102 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
}
int MeshDataTool::get_format() const {
-
return format;
}
int MeshDataTool::get_vertex_count() const {
-
return vertices.size();
}
-int MeshDataTool::get_edge_count() const {
+int MeshDataTool::get_edge_count() const {
return edges.size();
}
-int MeshDataTool::get_face_count() const {
+int MeshDataTool::get_face_count() const {
return faces.size();
}
Vector3 MeshDataTool::get_vertex(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector3());
return vertices[p_idx].vertex;
}
-void MeshDataTool::set_vertex(int p_idx, const Vector3 &p_vertex) {
+void MeshDataTool::set_vertex(int p_idx, const Vector3 &p_vertex) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].vertex = p_vertex;
}
Vector3 MeshDataTool::get_vertex_normal(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector3());
return vertices[p_idx].normal;
}
-void MeshDataTool::set_vertex_normal(int p_idx, const Vector3 &p_normal) {
+void MeshDataTool::set_vertex_normal(int p_idx, const Vector3 &p_normal) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].normal = p_normal;
format |= Mesh::ARRAY_FORMAT_NORMAL;
}
Plane MeshDataTool::get_vertex_tangent(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Plane());
return vertices[p_idx].tangent;
}
-void MeshDataTool::set_vertex_tangent(int p_idx, const Plane &p_tangent) {
+void MeshDataTool::set_vertex_tangent(int p_idx, const Plane &p_tangent) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].tangent = p_tangent;
format |= Mesh::ARRAY_FORMAT_TANGENT;
}
Vector2 MeshDataTool::get_vertex_uv(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector2());
return vertices[p_idx].uv;
}
-void MeshDataTool::set_vertex_uv(int p_idx, const Vector2 &p_uv) {
+void MeshDataTool::set_vertex_uv(int p_idx, const Vector2 &p_uv) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].uv = p_uv;
format |= Mesh::ARRAY_FORMAT_TEX_UV;
}
Vector2 MeshDataTool::get_vertex_uv2(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector2());
return vertices[p_idx].uv2;
}
-void MeshDataTool::set_vertex_uv2(int p_idx, const Vector2 &p_uv2) {
+void MeshDataTool::set_vertex_uv2(int p_idx, const Vector2 &p_uv2) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].uv2 = p_uv2;
format |= Mesh::ARRAY_FORMAT_TEX_UV2;
}
Color MeshDataTool::get_vertex_color(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Color());
return vertices[p_idx].color;
}
-void MeshDataTool::set_vertex_color(int p_idx, const Color &p_color) {
+void MeshDataTool::set_vertex_color(int p_idx, const Color &p_color) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].color = p_color;
format |= Mesh::ARRAY_FORMAT_COLOR;
}
Vector<int> MeshDataTool::get_vertex_bones(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<int>());
return vertices[p_idx].bones;
}
-void MeshDataTool::set_vertex_bones(int p_idx, const Vector<int> &p_bones) {
+void MeshDataTool::set_vertex_bones(int p_idx, const Vector<int> &p_bones) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].bones = p_bones;
format |= Mesh::ARRAY_FORMAT_BONES;
}
Vector<float> MeshDataTool::get_vertex_weights(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<float>());
return vertices[p_idx].weights;
}
+
void MeshDataTool::set_vertex_weights(int p_idx, const Vector<float> &p_weights) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].weights = p_weights;
@@ -430,75 +431,69 @@ void MeshDataTool::set_vertex_weights(int p_idx, const Vector<float> &p_weights)
}
Variant MeshDataTool::get_vertex_meta(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Variant());
return vertices[p_idx].meta;
}
void MeshDataTool::set_vertex_meta(int p_idx, const Variant &p_meta) {
-
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].meta = p_meta;
}
Vector<int> MeshDataTool::get_vertex_edges(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<int>());
return vertices[p_idx].edges;
}
-Vector<int> MeshDataTool::get_vertex_faces(int p_idx) const {
+Vector<int> MeshDataTool::get_vertex_faces(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<int>());
return vertices[p_idx].faces;
}
int MeshDataTool::get_edge_vertex(int p_edge, int p_vertex) const {
-
ERR_FAIL_INDEX_V(p_edge, edges.size(), -1);
ERR_FAIL_INDEX_V(p_vertex, 2, -1);
return edges[p_edge].vertex[p_vertex];
}
-Vector<int> MeshDataTool::get_edge_faces(int p_edge) const {
+Vector<int> MeshDataTool::get_edge_faces(int p_edge) const {
ERR_FAIL_INDEX_V(p_edge, edges.size(), Vector<int>());
return edges[p_edge].faces;
}
-Variant MeshDataTool::get_edge_meta(int p_idx) const {
+Variant MeshDataTool::get_edge_meta(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edges.size(), Variant());
return edges[p_idx].meta;
}
-void MeshDataTool::set_edge_meta(int p_idx, const Variant &p_meta) {
+void MeshDataTool::set_edge_meta(int p_idx, const Variant &p_meta) {
ERR_FAIL_INDEX(p_idx, edges.size());
edges.write[p_idx].meta = p_meta;
}
int MeshDataTool::get_face_vertex(int p_face, int p_vertex) const {
-
ERR_FAIL_INDEX_V(p_face, faces.size(), -1);
ERR_FAIL_INDEX_V(p_vertex, 3, -1);
return faces[p_face].v[p_vertex];
}
-int MeshDataTool::get_face_edge(int p_face, int p_vertex) const {
+int MeshDataTool::get_face_edge(int p_face, int p_vertex) const {
ERR_FAIL_INDEX_V(p_face, faces.size(), -1);
ERR_FAIL_INDEX_V(p_vertex, 3, -1);
return faces[p_face].edges[p_vertex];
}
-Variant MeshDataTool::get_face_meta(int p_face) const {
+Variant MeshDataTool::get_face_meta(int p_face) const {
ERR_FAIL_INDEX_V(p_face, faces.size(), Variant());
return faces[p_face].meta;
}
-void MeshDataTool::set_face_meta(int p_face, const Variant &p_meta) {
+void MeshDataTool::set_face_meta(int p_face, const Variant &p_meta) {
ERR_FAIL_INDEX(p_face, faces.size());
faces.write[p_face].meta = p_meta;
}
Vector3 MeshDataTool::get_face_normal(int p_face) const {
-
ERR_FAIL_INDEX_V(p_face, faces.size(), Vector3());
Vector3 v0 = vertices[faces[p_face].v[0]].vertex;
Vector3 v1 = vertices[faces[p_face].v[1]].vertex;
@@ -508,17 +503,14 @@ Vector3 MeshDataTool::get_face_normal(int p_face) const {
}
Ref<Material> MeshDataTool::get_material() const {
-
return material;
}
void MeshDataTool::set_material(const Ref<Material> &p_material) {
-
material = p_material;
}
void MeshDataTool::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("clear"), &MeshDataTool::clear);
ClassDB::bind_method(D_METHOD("create_from_surface", "mesh", "surface"), &MeshDataTool::create_from_surface);
ClassDB::bind_method(D_METHOD("commit_to_surface", "mesh"), &MeshDataTool::commit_to_surface);
@@ -578,6 +570,5 @@ void MeshDataTool::_bind_methods() {
}
MeshDataTool::MeshDataTool() {
-
clear();
}
diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h
index 5ac2c7e702..bf9f0dd25f 100644
--- a/scene/resources/mesh_data_tool.h
+++ b/scene/resources/mesh_data_tool.h
@@ -34,7 +34,6 @@
#include "scene/resources/mesh.h"
class MeshDataTool : public Reference {
-
GDCLASS(MeshDataTool, Reference);
int format;
@@ -55,7 +54,6 @@ class MeshDataTool : public Reference {
Vector<Vertex> vertices;
struct Edge {
-
int vertex[2];
Vector<int> faces;
Variant meta;
@@ -64,7 +62,6 @@ class MeshDataTool : public Reference {
Vector<Edge> edges;
struct Face {
-
int v[3];
int edges[3];
Variant meta;
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index 754cad4def..09b0d4b038 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -29,23 +29,21 @@
/*************************************************************************/
#include "mesh_library.h"
-#include "core/engine.h"
bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("item/")) {
-
int idx = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
- if (!item_map.has(idx))
+ if (!item_map.has(idx)) {
create_item(idx);
+ }
- if (what == "name")
+ if (what == "name") {
set_item_name(idx, p_value);
- else if (what == "mesh")
+ } else if (what == "mesh") {
set_item_mesh(idx, p_value);
- else if (what == "shape") {
+ } else if (what == "shape") {
Vector<ShapeData> shapes;
ShapeData sd;
sd.shape = p_value;
@@ -53,14 +51,15 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
set_item_shapes(idx, shapes);
} else if (what == "shapes") {
_set_item_shapes(idx, p_value);
- } else if (what == "preview")
+ } else if (what == "preview") {
set_item_preview(idx, p_value);
- else if (what == "navmesh")
+ } else if (what == "navmesh") {
set_item_navmesh(idx, p_value);
- else if (what == "navmesh_transform")
+ } else if (what == "navmesh_transform") {
set_item_navmesh_transform(idx, p_value);
- else
+ } else {
return false;
+ }
return true;
}
@@ -69,34 +68,32 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
}
bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
int idx = name.get_slicec('/', 1).to_int();
ERR_FAIL_COND_V(!item_map.has(idx), false);
String what = name.get_slicec('/', 2);
- if (what == "name")
+ if (what == "name") {
r_ret = get_item_name(idx);
- else if (what == "mesh")
+ } else if (what == "mesh") {
r_ret = get_item_mesh(idx);
- else if (what == "shapes")
+ } else if (what == "shapes") {
r_ret = _get_item_shapes(idx);
- else if (what == "navmesh")
+ } else if (what == "navmesh") {
r_ret = get_item_navmesh(idx);
- else if (what == "navmesh_transform")
+ } else if (what == "navmesh_transform") {
r_ret = get_item_navmesh_transform(idx);
- else if (what == "preview")
+ } else if (what == "preview") {
r_ret = get_item_preview(idx);
- else
+ } else {
return false;
+ }
return true;
}
void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
-
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
-
String name = "item/" + itos(E->key()) + "/";
p_list->push_back(PropertyInfo(Variant::STRING, name + "name"));
p_list->push_back(PropertyInfo(Variant::OBJECT, name + "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"));
@@ -104,12 +101,11 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::ARRAY, name + "shapes"));
p_list->push_back(PropertyInfo(Variant::OBJECT, name + "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"));
p_list->push_back(PropertyInfo(Variant::TRANSFORM, name + "navmesh_transform"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER));
}
}
void MeshLibrary::create_item(int p_item) {
-
ERR_FAIL_COND(p_item < 0);
ERR_FAIL_COND(item_map.has(p_item));
item_map[p_item] = Item();
@@ -117,7 +113,6 @@ void MeshLibrary::create_item(int p_item) {
}
void MeshLibrary::set_item_name(int p_item, const String &p_name) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].name = p_name;
emit_changed();
@@ -125,7 +120,6 @@ void MeshLibrary::set_item_name(int p_item, const String &p_name) {
}
void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].mesh = p_mesh;
notify_change_to_owners();
@@ -134,7 +128,6 @@ void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
}
void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].shapes = p_shapes;
_change_notify();
@@ -144,7 +137,6 @@ void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes)
}
void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].navmesh = p_navmesh;
_change_notify();
@@ -154,7 +146,6 @@ void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navm
}
void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_transform) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].navmesh_transform = p_transform;
notify_change_to_owners();
@@ -162,8 +153,7 @@ void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_tran
_change_notify();
}
-void MeshLibrary::set_item_preview(int p_item, const Ref<Texture> &p_preview) {
-
+void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].preview = p_preview;
emit_changed();
@@ -171,52 +161,40 @@ void MeshLibrary::set_item_preview(int p_item, const Ref<Texture> &p_preview) {
}
String MeshLibrary::get_item_name(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), "", "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].name;
}
Ref<Mesh> MeshLibrary::get_item_mesh(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Mesh>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].mesh;
}
Vector<MeshLibrary::ShapeData> MeshLibrary::get_item_shapes(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Vector<ShapeData>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].shapes;
}
Ref<NavigationMesh> MeshLibrary::get_item_navmesh(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<NavigationMesh>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].navmesh;
}
Transform MeshLibrary::get_item_navmesh_transform(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Transform(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].navmesh_transform;
}
-Ref<Texture> MeshLibrary::get_item_preview(int p_item) const {
-
- if (!Engine::get_singleton()->is_editor_hint()) {
- ERR_PRINT("MeshLibrary item previews are only generated in an editor context, which means they aren't available in a running project.");
- return Ref<Texture>();
- }
-
- ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
+Ref<Texture2D> MeshLibrary::get_item_preview(int p_item) const {
+ ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture2D>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].preview;
}
bool MeshLibrary::has_item(int p_item) const {
-
return item_map.has(p_item);
}
-void MeshLibrary::remove_item(int p_item) {
+void MeshLibrary::remove_item(int p_item) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map.erase(p_item);
notify_change_to_owners();
@@ -225,7 +203,6 @@ void MeshLibrary::remove_item(int p_item) {
}
void MeshLibrary::clear() {
-
item_map.clear();
notify_change_to_owners();
_change_notify();
@@ -233,12 +210,10 @@ void MeshLibrary::clear() {
}
Vector<int> MeshLibrary::get_item_list() const {
-
Vector<int> ret;
ret.resize(item_map.size());
int idx = 0;
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
-
ret.write[idx++] = E->key();
}
@@ -246,25 +221,23 @@ Vector<int> MeshLibrary::get_item_list() const {
}
int MeshLibrary::find_item_by_name(const String &p_name) const {
-
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
-
- if (E->get().name == p_name)
+ if (E->get().name == p_name) {
return E->key();
+ }
}
return -1;
}
int MeshLibrary::get_last_unused_item_id() const {
-
- if (!item_map.size())
+ if (!item_map.size()) {
return 0;
- else
+ } else {
return item_map.back()->key() + 1;
+ }
}
void MeshLibrary::_set_item_shapes(int p_item, const Array &p_shapes) {
-
ERR_FAIL_COND(p_shapes.size() & 1);
Vector<ShapeData> shapes;
for (int i = 0; i < p_shapes.size(); i += 2) {
@@ -281,7 +254,6 @@ void MeshLibrary::_set_item_shapes(int p_item, const Array &p_shapes) {
}
Array MeshLibrary::_get_item_shapes(int p_item) const {
-
Vector<ShapeData> shapes = get_item_shapes(p_item);
Array ret;
for (int i = 0; i < shapes.size(); i++) {
@@ -293,7 +265,6 @@ Array MeshLibrary::_get_item_shapes(int p_item) const {
}
void MeshLibrary::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_item", "id"), &MeshLibrary::create_item);
ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name);
ClassDB::bind_method(D_METHOD("set_item_mesh", "id", "mesh"), &MeshLibrary::set_item_mesh);
@@ -317,5 +288,6 @@ void MeshLibrary::_bind_methods() {
MeshLibrary::MeshLibrary() {
}
+
MeshLibrary::~MeshLibrary() {
}
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 471db74175..450e2c16e3 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -28,30 +28,29 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GRID_THEME_H
-#define GRID_THEME_H
+#ifndef MESH_LIBRARY_H
+#define MESH_LIBRARY_H
#include "core/map.h"
#include "core/resource.h"
#include "mesh.h"
-#include "scene/3d/navigation_mesh.h"
-#include "shape.h"
+#include "scene/3d/navigation_region_3d.h"
+#include "shape_3d.h"
class MeshLibrary : public Resource {
-
GDCLASS(MeshLibrary, Resource);
RES_BASE_EXTENSION("meshlib");
public:
struct ShapeData {
- Ref<Shape> shape;
+ Ref<Shape3D> shape;
Transform local_transform;
};
struct Item {
String name;
Ref<Mesh> mesh;
Vector<ShapeData> shapes;
- Ref<Texture> preview;
+ Ref<Texture2D> preview;
Transform navmesh_transform;
Ref<NavigationMesh> navmesh;
};
@@ -75,13 +74,13 @@ public:
void set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh);
void set_item_navmesh_transform(int p_item, const Transform &p_transform);
void set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes);
- void set_item_preview(int p_item, const Ref<Texture> &p_preview);
+ void set_item_preview(int p_item, const Ref<Texture2D> &p_preview);
String get_item_name(int p_item) const;
Ref<Mesh> get_item_mesh(int p_item) const;
Ref<NavigationMesh> get_item_navmesh(int p_item) const;
Transform get_item_navmesh_transform(int p_item) const;
Vector<ShapeData> get_item_shapes(int p_item) const;
- Ref<Texture> get_item_preview(int p_item) const;
+ Ref<Texture2D> get_item_preview(int p_item) const;
void remove_item(int p_item);
bool has_item(int p_item) const;
@@ -97,4 +96,4 @@ public:
~MeshLibrary();
};
-#endif // CUBE_GRID_THEME_H
+#endif // MESH_LIBRARY_H
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index ee831f36f5..f71cf383e5 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -29,22 +29,27 @@
/*************************************************************************/
#include "multimesh.h"
-#include "servers/visual_server.h"
-void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) {
- if (transform_format != TRANSFORM_3D)
+#include "servers/rendering_server.h"
+
+#ifndef DISABLE_DEPRECATED
+// Kept for compatibility from 3.x to 4.0.
+
+void MultiMesh::_set_transform_array(const Vector<Vector3> &p_array) {
+ if (transform_format != TRANSFORM_3D) {
return;
+ }
- const PoolVector<Vector3> &xforms = p_array;
+ const Vector<Vector3> &xforms = p_array;
int len = xforms.size();
ERR_FAIL_COND((len / 4) != instance_count);
- if (len == 0)
+ if (len == 0) {
return;
+ }
- PoolVector<Vector3>::Read r = xforms.read();
+ const Vector3 *r = xforms.ptr();
for (int i = 0; i < len / 4; i++) {
-
Transform t;
t.basis[0] = r[i * 4 + 0];
t.basis[1] = r[i * 4 + 1];
@@ -55,21 +60,21 @@ void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) {
}
}
-PoolVector<Vector3> MultiMesh::_get_transform_array() const {
-
- if (transform_format != TRANSFORM_3D)
- return PoolVector<Vector3>();
+Vector<Vector3> MultiMesh::_get_transform_array() const {
+ if (transform_format != TRANSFORM_3D) {
+ return Vector<Vector3>();
+ }
- if (instance_count == 0)
- return PoolVector<Vector3>();
+ if (instance_count == 0) {
+ return Vector<Vector3>();
+ }
- PoolVector<Vector3> xforms;
+ Vector<Vector3> xforms;
xforms.resize(instance_count * 4);
- PoolVector<Vector3>::Write w = xforms.write();
+ Vector3 *w = xforms.ptrw();
for (int i = 0; i < instance_count; i++) {
-
Transform t = get_instance_transform(i);
w[i * 4 + 0] = t.basis[0];
w[i * 4 + 1] = t.basis[1];
@@ -80,21 +85,21 @@ PoolVector<Vector3> MultiMesh::_get_transform_array() const {
return xforms;
}
-void MultiMesh::_set_transform_2d_array(const PoolVector<Vector2> &p_array) {
-
- if (transform_format != TRANSFORM_2D)
+void MultiMesh::_set_transform_2d_array(const Vector<Vector2> &p_array) {
+ if (transform_format != TRANSFORM_2D) {
return;
+ }
- const PoolVector<Vector2> &xforms = p_array;
+ const Vector<Vector2> &xforms = p_array;
int len = xforms.size();
ERR_FAIL_COND((len / 3) != instance_count);
- if (len == 0)
+ if (len == 0) {
return;
+ }
- PoolVector<Vector2>::Read r = xforms.read();
+ const Vector2 *r = xforms.ptr();
for (int i = 0; i < len / 3; i++) {
-
Transform2D t;
t.elements[0] = r[i * 3 + 0];
t.elements[1] = r[i * 3 + 1];
@@ -104,21 +109,21 @@ void MultiMesh::_set_transform_2d_array(const PoolVector<Vector2> &p_array) {
}
}
-PoolVector<Vector2> MultiMesh::_get_transform_2d_array() const {
-
- if (transform_format != TRANSFORM_2D)
- return PoolVector<Vector2>();
+Vector<Vector2> MultiMesh::_get_transform_2d_array() const {
+ if (transform_format != TRANSFORM_2D) {
+ return Vector<Vector2>();
+ }
- if (instance_count == 0)
- return PoolVector<Vector2>();
+ if (instance_count == 0) {
+ return Vector<Vector2>();
+ }
- PoolVector<Vector2> xforms;
+ Vector<Vector2> xforms;
xforms.resize(instance_count * 3);
- PoolVector<Vector2>::Write w = xforms.write();
+ Vector2 *w = xforms.ptrw();
for (int i = 0; i < instance_count; i++) {
-
Transform2D t = get_instance_transform_2d(i);
w[i * 3 + 0] = t.elements[0];
w[i * 3 + 1] = t.elements[1];
@@ -128,196 +133,183 @@ PoolVector<Vector2> MultiMesh::_get_transform_2d_array() const {
return xforms;
}
-void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) {
-
- const PoolVector<Color> &colors = p_array;
+void MultiMesh::_set_color_array(const Vector<Color> &p_array) {
+ const Vector<Color> &colors = p_array;
int len = colors.size();
- if (len == 0)
+ if (len == 0) {
return;
+ }
ERR_FAIL_COND(len != instance_count);
- PoolVector<Color>::Read r = colors.read();
+ const Color *r = colors.ptr();
for (int i = 0; i < len; i++) {
-
set_instance_color(i, r[i]);
}
}
-PoolVector<Color> MultiMesh::_get_color_array() const {
-
- if (instance_count == 0 || color_format == COLOR_NONE)
- return PoolVector<Color>();
+Vector<Color> MultiMesh::_get_color_array() const {
+ if (instance_count == 0 || !use_colors) {
+ return Vector<Color>();
+ }
- PoolVector<Color> colors;
+ Vector<Color> colors;
colors.resize(instance_count);
for (int i = 0; i < instance_count; i++) {
-
colors.set(i, get_instance_color(i));
}
return colors;
}
-void MultiMesh::_set_custom_data_array(const PoolVector<Color> &p_array) {
-
- const PoolVector<Color> &custom_datas = p_array;
+void MultiMesh::_set_custom_data_array(const Vector<Color> &p_array) {
+ const Vector<Color> &custom_datas = p_array;
int len = custom_datas.size();
- if (len == 0)
+ if (len == 0) {
return;
+ }
ERR_FAIL_COND(len != instance_count);
- PoolVector<Color>::Read r = custom_datas.read();
+ const Color *r = custom_datas.ptr();
for (int i = 0; i < len; i++) {
-
set_instance_custom_data(i, r[i]);
}
}
-PoolVector<Color> MultiMesh::_get_custom_data_array() const {
-
- if (instance_count == 0 || custom_data_format == CUSTOM_DATA_NONE)
- return PoolVector<Color>();
+Vector<Color> MultiMesh::_get_custom_data_array() const {
+ if (instance_count == 0 || !use_custom_data) {
+ return Vector<Color>();
+ }
- PoolVector<Color> custom_datas;
+ Vector<Color> custom_datas;
custom_datas.resize(instance_count);
for (int i = 0; i < instance_count; i++) {
-
custom_datas.set(i, get_instance_custom_data(i));
}
return custom_datas;
}
-void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) {
+#endif // DISABLE_DEPRECATED
+void MultiMesh::set_buffer(const Vector<float> &p_buffer) {
+ RS::get_singleton()->multimesh_set_buffer(multimesh, p_buffer);
+}
+
+Vector<float> MultiMesh::get_buffer() const {
+ return RS::get_singleton()->multimesh_get_buffer(multimesh);
+}
+
+void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) {
mesh = p_mesh;
- if (!mesh.is_null())
- VisualServer::get_singleton()->multimesh_set_mesh(multimesh, mesh->get_rid());
- else
- VisualServer::get_singleton()->multimesh_set_mesh(multimesh, RID());
+ if (!mesh.is_null()) {
+ RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, mesh->get_rid());
+ } else {
+ RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, RID());
+ }
}
Ref<Mesh> MultiMesh::get_mesh() const {
-
return mesh;
}
void MultiMesh::set_instance_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
- VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format), VS::MultimeshCustomDataFormat(custom_data_format));
+ RenderingServer::get_singleton()->multimesh_allocate(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data);
instance_count = p_count;
}
-int MultiMesh::get_instance_count() const {
+int MultiMesh::get_instance_count() const {
return instance_count;
}
void MultiMesh::set_visible_instance_count(int p_count) {
ERR_FAIL_COND(p_count < -1);
- VisualServer::get_singleton()->multimesh_set_visible_instances(multimesh, p_count);
+ ERR_FAIL_COND(p_count > instance_count);
+ RenderingServer::get_singleton()->multimesh_set_visible_instances(multimesh, p_count);
visible_instance_count = p_count;
}
-int MultiMesh::get_visible_instance_count() const {
+int MultiMesh::get_visible_instance_count() const {
return visible_instance_count;
}
void MultiMesh::set_instance_transform(int p_instance, const Transform &p_transform) {
-
- VisualServer::get_singleton()->multimesh_instance_set_transform(multimesh, p_instance, p_transform);
+ RenderingServer::get_singleton()->multimesh_instance_set_transform(multimesh, p_instance, p_transform);
}
void MultiMesh::set_instance_transform_2d(int p_instance, const Transform2D &p_transform) {
-
- VisualServer::get_singleton()->multimesh_instance_set_transform_2d(multimesh, p_instance, p_transform);
+ RenderingServer::get_singleton()->multimesh_instance_set_transform_2d(multimesh, p_instance, p_transform);
}
Transform MultiMesh::get_instance_transform(int p_instance) const {
-
- return VisualServer::get_singleton()->multimesh_instance_get_transform(multimesh, p_instance);
+ return RenderingServer::get_singleton()->multimesh_instance_get_transform(multimesh, p_instance);
}
Transform2D MultiMesh::get_instance_transform_2d(int p_instance) const {
-
- return VisualServer::get_singleton()->multimesh_instance_get_transform_2d(multimesh, p_instance);
+ return RenderingServer::get_singleton()->multimesh_instance_get_transform_2d(multimesh, p_instance);
}
void MultiMesh::set_instance_color(int p_instance, const Color &p_color) {
-
- VisualServer::get_singleton()->multimesh_instance_set_color(multimesh, p_instance, p_color);
+ RenderingServer::get_singleton()->multimesh_instance_set_color(multimesh, p_instance, p_color);
}
-Color MultiMesh::get_instance_color(int p_instance) const {
- return VisualServer::get_singleton()->multimesh_instance_get_color(multimesh, p_instance);
+Color MultiMesh::get_instance_color(int p_instance) const {
+ return RenderingServer::get_singleton()->multimesh_instance_get_color(multimesh, p_instance);
}
void MultiMesh::set_instance_custom_data(int p_instance, const Color &p_custom_data) {
-
- VisualServer::get_singleton()->multimesh_instance_set_custom_data(multimesh, p_instance, p_custom_data);
-}
-Color MultiMesh::get_instance_custom_data(int p_instance) const {
-
- return VisualServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance);
+ RenderingServer::get_singleton()->multimesh_instance_set_custom_data(multimesh, p_instance, p_custom_data);
}
-void MultiMesh::set_as_bulk_array(const PoolVector<float> &p_array) {
-
- VisualServer::get_singleton()->multimesh_set_as_bulk_array(multimesh, p_array);
+Color MultiMesh::get_instance_custom_data(int p_instance) const {
+ return RenderingServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance);
}
AABB MultiMesh::get_aabb() const {
-
- return VisualServer::get_singleton()->multimesh_get_aabb(multimesh);
+ return RenderingServer::get_singleton()->multimesh_get_aabb(multimesh);
}
RID MultiMesh::get_rid() const {
-
return multimesh;
}
-void MultiMesh::set_color_format(ColorFormat p_color_format) {
-
+void MultiMesh::set_use_colors(bool p_enable) {
ERR_FAIL_COND(instance_count > 0);
- color_format = p_color_format;
+ use_colors = p_enable;
}
-MultiMesh::ColorFormat MultiMesh::get_color_format() const {
-
- return color_format;
+bool MultiMesh::is_using_colors() const {
+ return use_colors;
}
-void MultiMesh::set_custom_data_format(CustomDataFormat p_custom_data_format) {
-
+void MultiMesh::set_use_custom_data(bool p_enable) {
ERR_FAIL_COND(instance_count > 0);
- custom_data_format = p_custom_data_format;
+ use_custom_data = p_enable;
}
-MultiMesh::CustomDataFormat MultiMesh::get_custom_data_format() const {
-
- return custom_data_format;
+bool MultiMesh::is_using_custom_data() const {
+ return use_custom_data;
}
void MultiMesh::set_transform_format(TransformFormat p_transform_format) {
-
ERR_FAIL_COND(instance_count > 0);
transform_format = p_transform_format;
}
-MultiMesh::TransformFormat MultiMesh::get_transform_format() const {
+MultiMesh::TransformFormat MultiMesh::get_transform_format() const {
return transform_format;
}
void MultiMesh::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MultiMesh::set_mesh);
ClassDB::bind_method(D_METHOD("get_mesh"), &MultiMesh::get_mesh);
- ClassDB::bind_method(D_METHOD("set_color_format", "format"), &MultiMesh::set_color_format);
- ClassDB::bind_method(D_METHOD("get_color_format"), &MultiMesh::get_color_format);
- ClassDB::bind_method(D_METHOD("set_custom_data_format", "format"), &MultiMesh::set_custom_data_format);
- ClassDB::bind_method(D_METHOD("get_custom_data_format"), &MultiMesh::get_custom_data_format);
+ ClassDB::bind_method(D_METHOD("set_use_colors", "enable"), &MultiMesh::set_use_colors);
+ ClassDB::bind_method(D_METHOD("is_using_colors"), &MultiMesh::is_using_colors);
+ ClassDB::bind_method(D_METHOD("set_use_custom_data", "enable"), &MultiMesh::set_use_custom_data);
+ ClassDB::bind_method(D_METHOD("is_using_custom_data"), &MultiMesh::is_using_custom_data);
ClassDB::bind_method(D_METHOD("set_transform_format", "format"), &MultiMesh::set_transform_format);
ClassDB::bind_method(D_METHOD("get_transform_format"), &MultiMesh::get_transform_format);
@@ -333,9 +325,21 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color);
ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data);
ClassDB::bind_method(D_METHOD("get_instance_custom_data", "instance"), &MultiMesh::get_instance_custom_data);
- ClassDB::bind_method(D_METHOD("set_as_bulk_array", "array"), &MultiMesh::set_as_bulk_array);
ClassDB::bind_method(D_METHOD("get_aabb"), &MultiMesh::get_aabb);
+ ClassDB::bind_method(D_METHOD("get_buffer"), &MultiMesh::get_buffer);
+ ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &MultiMesh::set_buffer);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_colors"), "set_use_colors", "is_using_colors");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_data"), "set_use_custom_data", "is_using_custom_data");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "buffer", PROPERTY_HINT_NONE), "set_buffer", "get_buffer");
+
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
ClassDB::bind_method(D_METHOD("_set_transform_array"), &MultiMesh::_set_transform_array);
ClassDB::bind_method(D_METHOD("_get_transform_array"), &MultiMesh::_get_transform_array);
ClassDB::bind_method(D_METHOD("_set_transform_2d_array"), &MultiMesh::_set_transform_2d_array);
@@ -345,40 +349,25 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_custom_data_array"), &MultiMesh::_set_custom_data_array);
ClassDB::bind_method(D_METHOD("_get_custom_data_array"), &MultiMesh::_get_custom_data_array);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "color_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_color_format", "get_color_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_custom_data_format", "get_custom_data_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_2d_array", "_get_transform_2d_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_custom_data_array", "_get_custom_data_array");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_array", "_get_transform_array");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_2d_array", "_get_transform_2d_array");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", 0), "_set_color_array", "_get_color_array");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", 0), "_set_custom_data_array", "_get_custom_data_array");
+#endif
BIND_ENUM_CONSTANT(TRANSFORM_2D);
BIND_ENUM_CONSTANT(TRANSFORM_3D);
-
- BIND_ENUM_CONSTANT(COLOR_NONE);
- BIND_ENUM_CONSTANT(COLOR_8BIT);
- BIND_ENUM_CONSTANT(COLOR_FLOAT);
-
- BIND_ENUM_CONSTANT(CUSTOM_DATA_NONE);
- BIND_ENUM_CONSTANT(CUSTOM_DATA_8BIT);
- BIND_ENUM_CONSTANT(CUSTOM_DATA_FLOAT);
}
MultiMesh::MultiMesh() {
-
- multimesh = VisualServer::get_singleton()->multimesh_create();
- color_format = COLOR_NONE;
- custom_data_format = CUSTOM_DATA_NONE;
+ multimesh = RenderingServer::get_singleton()->multimesh_create();
+ use_colors = false;
+ use_custom_data = false;
transform_format = TRANSFORM_2D;
visible_instance_count = -1;
instance_count = 0;
}
MultiMesh::~MultiMesh() {
-
- VisualServer::get_singleton()->free(multimesh);
+ RenderingServer::get_singleton()->free(multimesh);
}
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index 9394737799..16f5998a04 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -32,64 +32,56 @@
#define MULTIMESH_H
#include "scene/resources/mesh.h"
-#include "servers/visual_server.h"
+#include "servers/rendering_server.h"
class MultiMesh : public Resource {
-
GDCLASS(MultiMesh, Resource);
RES_BASE_EXTENSION("multimesh");
public:
enum TransformFormat {
- TRANSFORM_2D = VS::MULTIMESH_TRANSFORM_2D,
- TRANSFORM_3D = VS::MULTIMESH_TRANSFORM_3D
- };
-
- enum ColorFormat {
- COLOR_NONE = VS::MULTIMESH_COLOR_NONE,
- COLOR_8BIT = VS::MULTIMESH_COLOR_8BIT,
- COLOR_FLOAT = VS::MULTIMESH_COLOR_FLOAT,
- };
-
- enum CustomDataFormat {
- CUSTOM_DATA_NONE,
- CUSTOM_DATA_8BIT,
- CUSTOM_DATA_FLOAT,
+ TRANSFORM_2D = RS::MULTIMESH_TRANSFORM_2D,
+ TRANSFORM_3D = RS::MULTIMESH_TRANSFORM_3D
};
private:
Ref<Mesh> mesh;
RID multimesh;
TransformFormat transform_format;
- ColorFormat color_format;
- CustomDataFormat custom_data_format;
+ bool use_colors;
+ bool use_custom_data;
int instance_count;
int visible_instance_count;
protected:
static void _bind_methods();
- void _set_transform_array(const PoolVector<Vector3> &p_array);
- PoolVector<Vector3> _get_transform_array() const;
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
+ void _set_transform_array(const Vector<Vector3> &p_array);
+ Vector<Vector3> _get_transform_array() const;
- void _set_transform_2d_array(const PoolVector<Vector2> &p_array);
- PoolVector<Vector2> _get_transform_2d_array() const;
+ void _set_transform_2d_array(const Vector<Vector2> &p_array);
+ Vector<Vector2> _get_transform_2d_array() const;
- void _set_color_array(const PoolVector<Color> &p_array);
- PoolVector<Color> _get_color_array() const;
+ void _set_color_array(const Vector<Color> &p_array);
+ Vector<Color> _get_color_array() const;
- void _set_custom_data_array(const PoolVector<Color> &p_array);
- PoolVector<Color> _get_custom_data_array() const;
+ void _set_custom_data_array(const Vector<Color> &p_array);
+ Vector<Color> _get_custom_data_array() const;
+#endif
+ void set_buffer(const Vector<float> &p_buffer);
+ Vector<float> get_buffer() const;
public:
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
- void set_color_format(ColorFormat p_color_format);
- ColorFormat get_color_format() const;
+ void set_use_colors(bool p_enable);
+ bool is_using_colors() const;
- void set_custom_data_format(CustomDataFormat p_custom_data_format);
- CustomDataFormat get_custom_data_format() const;
+ void set_use_custom_data(bool p_enable);
+ bool is_using_custom_data() const;
void set_transform_format(TransformFormat p_transform_format);
TransformFormat get_transform_format() const;
@@ -111,18 +103,14 @@ public:
void set_instance_custom_data(int p_instance, const Color &p_custom_data);
Color get_instance_custom_data(int p_instance) const;
- void set_as_bulk_array(const PoolVector<float> &p_array);
-
virtual AABB get_aabb() const;
- virtual RID get_rid() const;
+ virtual RID get_rid() const override;
MultiMesh();
~MultiMesh();
};
VARIANT_ENUM_CAST(MultiMesh::TransformFormat);
-VARIANT_ENUM_CAST(MultiMesh::ColorFormat);
-VARIANT_ENUM_CAST(MultiMesh::CustomDataFormat);
#endif // MULTI_MESH_H
diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
new file mode 100644
index 0000000000..e815da5d45
--- /dev/null
+++ b/scene/resources/navigation_mesh.cpp
@@ -0,0 +1,536 @@
+/*************************************************************************/
+/* navigation_mesh.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "navigation_mesh.h"
+
+void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
+ vertices = Vector<Vector3>();
+ clear_polygons();
+
+ for (int i = 0; i < p_mesh->get_surface_count(); i++) {
+ if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
+ continue;
+ }
+ Array arr = p_mesh->surface_get_arrays(i);
+ Vector<Vector3> varr = arr[Mesh::ARRAY_VERTEX];
+ Vector<int> iarr = arr[Mesh::ARRAY_INDEX];
+ if (varr.size() == 0 || iarr.size() == 0) {
+ continue;
+ }
+
+ int from = vertices.size();
+ vertices.append_array(varr);
+ int rlen = iarr.size();
+ const int *r = iarr.ptr();
+
+ for (int j = 0; j < rlen; j += 3) {
+ Vector<int> vi;
+ vi.resize(3);
+ vi.write[0] = r[j + 0] + from;
+ vi.write[1] = r[j + 1] + from;
+ vi.write[2] = r[j + 2] + from;
+
+ add_polygon(vi);
+ }
+ }
+}
+
+void NavigationMesh::set_sample_partition_type(int p_value) {
+ ERR_FAIL_COND(p_value >= SAMPLE_PARTITION_MAX);
+ partition_type = static_cast<SamplePartitionType>(p_value);
+}
+
+int NavigationMesh::get_sample_partition_type() const {
+ return static_cast<int>(partition_type);
+}
+
+void NavigationMesh::set_parsed_geometry_type(int p_value) {
+ ERR_FAIL_COND(p_value >= PARSED_GEOMETRY_MAX);
+ parsed_geometry_type = static_cast<ParsedGeometryType>(p_value);
+ _change_notify();
+}
+
+int NavigationMesh::get_parsed_geometry_type() const {
+ return parsed_geometry_type;
+}
+
+void NavigationMesh::set_collision_mask(uint32_t p_mask) {
+ collision_mask = p_mask;
+}
+
+uint32_t NavigationMesh::get_collision_mask() const {
+ return collision_mask;
+}
+
+void NavigationMesh::set_collision_mask_bit(int p_bit, bool p_value) {
+ uint32_t mask = get_collision_mask();
+ if (p_value) {
+ mask |= 1 << p_bit;
+ } else {
+ mask &= ~(1 << p_bit);
+ }
+ set_collision_mask(mask);
+}
+
+bool NavigationMesh::get_collision_mask_bit(int p_bit) const {
+ return get_collision_mask() & (1 << p_bit);
+}
+
+void NavigationMesh::set_source_geometry_mode(int p_geometry_mode) {
+ ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX);
+ source_geometry_mode = static_cast<SourceGeometryMode>(p_geometry_mode);
+ _change_notify();
+}
+
+int NavigationMesh::get_source_geometry_mode() const {
+ return source_geometry_mode;
+}
+
+void NavigationMesh::set_source_group_name(StringName p_group_name) {
+ source_group_name = p_group_name;
+}
+
+StringName NavigationMesh::get_source_group_name() const {
+ return source_group_name;
+}
+
+void NavigationMesh::set_cell_size(float p_value) {
+ cell_size = p_value;
+}
+
+float NavigationMesh::get_cell_size() const {
+ return cell_size;
+}
+
+void NavigationMesh::set_cell_height(float p_value) {
+ cell_height = p_value;
+}
+
+float NavigationMesh::get_cell_height() const {
+ return cell_height;
+}
+
+void NavigationMesh::set_agent_height(float p_value) {
+ agent_height = p_value;
+}
+
+float NavigationMesh::get_agent_height() const {
+ return agent_height;
+}
+
+void NavigationMesh::set_agent_radius(float p_value) {
+ agent_radius = p_value;
+}
+
+float NavigationMesh::get_agent_radius() {
+ return agent_radius;
+}
+
+void NavigationMesh::set_agent_max_climb(float p_value) {
+ agent_max_climb = p_value;
+}
+
+float NavigationMesh::get_agent_max_climb() const {
+ return agent_max_climb;
+}
+
+void NavigationMesh::set_agent_max_slope(float p_value) {
+ agent_max_slope = p_value;
+}
+
+float NavigationMesh::get_agent_max_slope() const {
+ return agent_max_slope;
+}
+
+void NavigationMesh::set_region_min_size(float p_value) {
+ region_min_size = p_value;
+}
+
+float NavigationMesh::get_region_min_size() const {
+ return region_min_size;
+}
+
+void NavigationMesh::set_region_merge_size(float p_value) {
+ region_merge_size = p_value;
+}
+
+float NavigationMesh::get_region_merge_size() const {
+ return region_merge_size;
+}
+
+void NavigationMesh::set_edge_max_length(float p_value) {
+ edge_max_length = p_value;
+}
+
+float NavigationMesh::get_edge_max_length() const {
+ return edge_max_length;
+}
+
+void NavigationMesh::set_edge_max_error(float p_value) {
+ edge_max_error = p_value;
+}
+
+float NavigationMesh::get_edge_max_error() const {
+ return edge_max_error;
+}
+
+void NavigationMesh::set_verts_per_poly(float p_value) {
+ verts_per_poly = p_value;
+}
+
+float NavigationMesh::get_verts_per_poly() const {
+ return verts_per_poly;
+}
+
+void NavigationMesh::set_detail_sample_distance(float p_value) {
+ detail_sample_distance = p_value;
+}
+
+float NavigationMesh::get_detail_sample_distance() const {
+ return detail_sample_distance;
+}
+
+void NavigationMesh::set_detail_sample_max_error(float p_value) {
+ detail_sample_max_error = p_value;
+}
+
+float NavigationMesh::get_detail_sample_max_error() const {
+ return detail_sample_max_error;
+}
+
+void NavigationMesh::set_filter_low_hanging_obstacles(bool p_value) {
+ filter_low_hanging_obstacles = p_value;
+}
+
+bool NavigationMesh::get_filter_low_hanging_obstacles() const {
+ return filter_low_hanging_obstacles;
+}
+
+void NavigationMesh::set_filter_ledge_spans(bool p_value) {
+ filter_ledge_spans = p_value;
+}
+
+bool NavigationMesh::get_filter_ledge_spans() const {
+ return filter_ledge_spans;
+}
+
+void NavigationMesh::set_filter_walkable_low_height_spans(bool p_value) {
+ filter_walkable_low_height_spans = p_value;
+}
+
+bool NavigationMesh::get_filter_walkable_low_height_spans() const {
+ return filter_walkable_low_height_spans;
+}
+
+void NavigationMesh::set_vertices(const Vector<Vector3> &p_vertices) {
+ vertices = p_vertices;
+ _change_notify();
+}
+
+Vector<Vector3> NavigationMesh::get_vertices() const {
+ return vertices;
+}
+
+void NavigationMesh::_set_polygons(const Array &p_array) {
+ polygons.resize(p_array.size());
+ for (int i = 0; i < p_array.size(); i++) {
+ polygons.write[i].indices = p_array[i];
+ }
+ _change_notify();
+}
+
+Array NavigationMesh::_get_polygons() const {
+ Array ret;
+ ret.resize(polygons.size());
+ for (int i = 0; i < ret.size(); i++) {
+ ret[i] = polygons[i].indices;
+ }
+
+ return ret;
+}
+
+void NavigationMesh::add_polygon(const Vector<int> &p_polygon) {
+ Polygon polygon;
+ polygon.indices = p_polygon;
+ polygons.push_back(polygon);
+ _change_notify();
+}
+
+int NavigationMesh::get_polygon_count() const {
+ return polygons.size();
+}
+
+Vector<int> NavigationMesh::get_polygon(int p_idx) {
+ ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
+ return polygons[p_idx].indices;
+}
+
+void NavigationMesh::clear_polygons() {
+ polygons.clear();
+}
+
+Ref<Mesh> NavigationMesh::get_debug_mesh() {
+ if (debug_mesh.is_valid()) {
+ return debug_mesh;
+ }
+
+ Vector<Vector3> vertices = get_vertices();
+ const Vector3 *vr = vertices.ptr();
+ List<Face3> faces;
+ for (int i = 0; i < get_polygon_count(); i++) {
+ Vector<int> p = get_polygon(i);
+
+ for (int j = 2; j < p.size(); j++) {
+ Face3 f;
+ f.vertex[0] = vr[p[0]];
+ f.vertex[1] = vr[p[j - 1]];
+ f.vertex[2] = vr[p[j]];
+
+ faces.push_back(f);
+ }
+ }
+
+ Map<_EdgeKey, bool> edge_map;
+ Vector<Vector3> tmeshfaces;
+ tmeshfaces.resize(faces.size() * 3);
+
+ {
+ Vector3 *tw = tmeshfaces.ptrw();
+ int tidx = 0;
+
+ for (List<Face3>::Element *E = faces.front(); E; E = E->next()) {
+ const Face3 &f = E->get();
+
+ for (int j = 0; j < 3; j++) {
+ tw[tidx++] = f.vertex[j];
+ _EdgeKey ek;
+ ek.from = f.vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
+ ek.to = f.vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
+ if (ek.from < ek.to) {
+ SWAP(ek.from, ek.to);
+ }
+
+ Map<_EdgeKey, bool>::Element *F = edge_map.find(ek);
+
+ if (F) {
+ F->get() = false;
+
+ } else {
+ edge_map[ek] = true;
+ }
+ }
+ }
+ }
+ List<Vector3> lines;
+
+ for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) {
+ if (E->get()) {
+ lines.push_back(E->key().from);
+ lines.push_back(E->key().to);
+ }
+ }
+
+ Vector<Vector3> varr;
+ varr.resize(lines.size());
+ {
+ Vector3 *w = varr.ptrw();
+ int idx = 0;
+ for (List<Vector3>::Element *E = lines.front(); E; E = E->next()) {
+ w[idx++] = E->get();
+ }
+ }
+
+ debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+
+ Array arr;
+ arr.resize(Mesh::ARRAY_MAX);
+ arr[Mesh::ARRAY_VERTEX] = varr;
+
+ debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, arr);
+
+ return debug_mesh;
+}
+
+void NavigationMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_sample_partition_type", "sample_partition_type"), &NavigationMesh::set_sample_partition_type);
+ ClassDB::bind_method(D_METHOD("get_sample_partition_type"), &NavigationMesh::get_sample_partition_type);
+
+ ClassDB::bind_method(D_METHOD("set_parsed_geometry_type", "geometry_type"), &NavigationMesh::set_parsed_geometry_type);
+ ClassDB::bind_method(D_METHOD("get_parsed_geometry_type"), &NavigationMesh::get_parsed_geometry_type);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &NavigationMesh::set_collision_mask);
+ ClassDB::bind_method(D_METHOD("get_collision_mask"), &NavigationMesh::get_collision_mask);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &NavigationMesh::set_collision_mask_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &NavigationMesh::get_collision_mask_bit);
+
+ ClassDB::bind_method(D_METHOD("set_source_geometry_mode", "mask"), &NavigationMesh::set_source_geometry_mode);
+ ClassDB::bind_method(D_METHOD("get_source_geometry_mode"), &NavigationMesh::get_source_geometry_mode);
+
+ ClassDB::bind_method(D_METHOD("set_source_group_name", "mask"), &NavigationMesh::set_source_group_name);
+ ClassDB::bind_method(D_METHOD("get_source_group_name"), &NavigationMesh::get_source_group_name);
+
+ ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &NavigationMesh::set_cell_size);
+ ClassDB::bind_method(D_METHOD("get_cell_size"), &NavigationMesh::get_cell_size);
+
+ ClassDB::bind_method(D_METHOD("set_cell_height", "cell_height"), &NavigationMesh::set_cell_height);
+ ClassDB::bind_method(D_METHOD("get_cell_height"), &NavigationMesh::get_cell_height);
+
+ ClassDB::bind_method(D_METHOD("set_agent_height", "agent_height"), &NavigationMesh::set_agent_height);
+ ClassDB::bind_method(D_METHOD("get_agent_height"), &NavigationMesh::get_agent_height);
+
+ ClassDB::bind_method(D_METHOD("set_agent_radius", "agent_radius"), &NavigationMesh::set_agent_radius);
+ ClassDB::bind_method(D_METHOD("get_agent_radius"), &NavigationMesh::get_agent_radius);
+
+ ClassDB::bind_method(D_METHOD("set_agent_max_climb", "agent_max_climb"), &NavigationMesh::set_agent_max_climb);
+ ClassDB::bind_method(D_METHOD("get_agent_max_climb"), &NavigationMesh::get_agent_max_climb);
+
+ ClassDB::bind_method(D_METHOD("set_agent_max_slope", "agent_max_slope"), &NavigationMesh::set_agent_max_slope);
+ ClassDB::bind_method(D_METHOD("get_agent_max_slope"), &NavigationMesh::get_agent_max_slope);
+
+ ClassDB::bind_method(D_METHOD("set_region_min_size", "region_min_size"), &NavigationMesh::set_region_min_size);
+ ClassDB::bind_method(D_METHOD("get_region_min_size"), &NavigationMesh::get_region_min_size);
+
+ ClassDB::bind_method(D_METHOD("set_region_merge_size", "region_merge_size"), &NavigationMesh::set_region_merge_size);
+ ClassDB::bind_method(D_METHOD("get_region_merge_size"), &NavigationMesh::get_region_merge_size);
+
+ ClassDB::bind_method(D_METHOD("set_edge_max_length", "edge_max_length"), &NavigationMesh::set_edge_max_length);
+ ClassDB::bind_method(D_METHOD("get_edge_max_length"), &NavigationMesh::get_edge_max_length);
+
+ ClassDB::bind_method(D_METHOD("set_edge_max_error", "edge_max_error"), &NavigationMesh::set_edge_max_error);
+ ClassDB::bind_method(D_METHOD("get_edge_max_error"), &NavigationMesh::get_edge_max_error);
+
+ ClassDB::bind_method(D_METHOD("set_verts_per_poly", "verts_per_poly"), &NavigationMesh::set_verts_per_poly);
+ ClassDB::bind_method(D_METHOD("get_verts_per_poly"), &NavigationMesh::get_verts_per_poly);
+
+ ClassDB::bind_method(D_METHOD("set_detail_sample_distance", "detail_sample_dist"), &NavigationMesh::set_detail_sample_distance);
+ ClassDB::bind_method(D_METHOD("get_detail_sample_distance"), &NavigationMesh::get_detail_sample_distance);
+
+ ClassDB::bind_method(D_METHOD("set_detail_sample_max_error", "detail_sample_max_error"), &NavigationMesh::set_detail_sample_max_error);
+ ClassDB::bind_method(D_METHOD("get_detail_sample_max_error"), &NavigationMesh::get_detail_sample_max_error);
+
+ ClassDB::bind_method(D_METHOD("set_filter_low_hanging_obstacles", "filter_low_hanging_obstacles"), &NavigationMesh::set_filter_low_hanging_obstacles);
+ ClassDB::bind_method(D_METHOD("get_filter_low_hanging_obstacles"), &NavigationMesh::get_filter_low_hanging_obstacles);
+
+ ClassDB::bind_method(D_METHOD("set_filter_ledge_spans", "filter_ledge_spans"), &NavigationMesh::set_filter_ledge_spans);
+ ClassDB::bind_method(D_METHOD("get_filter_ledge_spans"), &NavigationMesh::get_filter_ledge_spans);
+
+ ClassDB::bind_method(D_METHOD("set_filter_walkable_low_height_spans", "filter_walkable_low_height_spans"), &NavigationMesh::set_filter_walkable_low_height_spans);
+ ClassDB::bind_method(D_METHOD("get_filter_walkable_low_height_spans"), &NavigationMesh::get_filter_walkable_low_height_spans);
+
+ ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationMesh::set_vertices);
+ ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationMesh::get_vertices);
+
+ ClassDB::bind_method(D_METHOD("add_polygon", "polygon"), &NavigationMesh::add_polygon);
+ ClassDB::bind_method(D_METHOD("get_polygon_count"), &NavigationMesh::get_polygon_count);
+ ClassDB::bind_method(D_METHOD("get_polygon", "idx"), &NavigationMesh::get_polygon);
+ ClassDB::bind_method(D_METHOD("clear_polygons"), &NavigationMesh::clear_polygons);
+
+ ClassDB::bind_method(D_METHOD("create_from_mesh", "mesh"), &NavigationMesh::create_from_mesh);
+
+ ClassDB::bind_method(D_METHOD("_set_polygons", "polygons"), &NavigationMesh::_set_polygons);
+ ClassDB::bind_method(D_METHOD("_get_polygons"), &NavigationMesh::_get_polygons);
+
+ BIND_CONSTANT(SAMPLE_PARTITION_WATERSHED);
+ BIND_CONSTANT(SAMPLE_PARTITION_MONOTONE);
+ BIND_CONSTANT(SAMPLE_PARTITION_LAYERS);
+
+ BIND_CONSTANT(PARSED_GEOMETRY_MESH_INSTANCES);
+ BIND_CONSTANT(PARSED_GEOMETRY_STATIC_COLLIDERS);
+ BIND_CONSTANT(PARSED_GEOMETRY_BOTH);
+
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons");
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sample_partition_type/sample_partition_type", PROPERTY_HINT_ENUM, "Watershed,Monotone,Layers"), "set_sample_partition_type", "get_sample_partition_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/parsed_geometry_type", PROPERTY_HINT_ENUM, "Mesh Instances,Static Colliders,Both"), "set_parsed_geometry_type", "get_parsed_geometry_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/source_geometry_mode", PROPERTY_HINT_ENUM, "Navmesh Children, Group With Children, Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry/source_group_name"), "set_source_group_name", "get_source_group_name");
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell/size", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_size", "get_cell_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell/height", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_height", "get_cell_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/height", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_height", "get_agent_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/radius", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_radius", "get_agent_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/max_climb", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_max_climb", "get_agent_max_climb");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/max_slope", PROPERTY_HINT_RANGE, "0.0,90.0,0.1"), "set_agent_max_slope", "get_agent_max_slope");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "region/min_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_min_size", "get_region_min_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "region/merge_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_merge_size", "get_region_merge_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge/max_error", PROPERTY_HINT_RANGE, "0.1,3.0,0.01,or_greater"), "set_edge_max_error", "get_edge_max_error");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "polygon/verts_per_poly", PROPERTY_HINT_RANGE, "3.0,12.0,1.0,or_greater"), "set_verts_per_poly", "get_verts_per_poly");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "detail/sample_max_error", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_max_error", "get_detail_sample_max_error");
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/ledge_spans"), "set_filter_ledge_spans", "get_filter_ledge_spans");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/filter_walkable_low_height_spans"), "set_filter_walkable_low_height_spans", "get_filter_walkable_low_height_spans");
+}
+
+void NavigationMesh::_validate_property(PropertyInfo &property) const {
+ if (property.name == "geometry/collision_mask") {
+ if (parsed_geometry_type == PARSED_GEOMETRY_MESH_INSTANCES) {
+ property.usage = 0;
+ return;
+ }
+ }
+
+ if (property.name == "geometry/source_group_name") {
+ if (source_geometry_mode == SOURCE_GEOMETRY_NAVMESH_CHILDREN) {
+ property.usage = 0;
+ return;
+ }
+ }
+}
+
+NavigationMesh::NavigationMesh() {
+ cell_size = 0.3f;
+ cell_height = 0.2f;
+ agent_height = 2.0f;
+ agent_radius = 0.6f;
+ agent_max_climb = 0.9f;
+ agent_max_slope = 45.0f;
+ region_min_size = 8.0f;
+ region_merge_size = 20.0f;
+ edge_max_length = 12.0f;
+ edge_max_error = 1.3f;
+ verts_per_poly = 6.0f;
+ detail_sample_distance = 6.0f;
+ detail_sample_max_error = 1.0f;
+
+ partition_type = SAMPLE_PARTITION_WATERSHED;
+ parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES;
+ collision_mask = 0xFFFFFFFF;
+ source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN;
+ source_group_name = "navmesh";
+ filter_low_hanging_obstacles = false;
+ filter_ledge_spans = false;
+ filter_walkable_low_height_spans = false;
+}
diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h
new file mode 100644
index 0000000000..b94f4408e1
--- /dev/null
+++ b/scene/resources/navigation_mesh.h
@@ -0,0 +1,193 @@
+/*************************************************************************/
+/* navigation_mesh.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NAVIGATION_MESH_H
+#define NAVIGATION_MESH_H
+
+#include "scene/resources/mesh.h"
+
+class Mesh;
+
+class NavigationMesh : public Resource {
+ GDCLASS(NavigationMesh, Resource);
+
+ Vector<Vector3> vertices;
+ struct Polygon {
+ Vector<int> indices;
+ };
+ Vector<Polygon> polygons;
+ Ref<ArrayMesh> debug_mesh;
+
+ struct _EdgeKey {
+ Vector3 from;
+ Vector3 to;
+
+ bool operator<(const _EdgeKey &p_with) const { return from == p_with.from ? to < p_with.to : from < p_with.from; }
+ };
+
+protected:
+ static void _bind_methods();
+ virtual void _validate_property(PropertyInfo &property) const override;
+
+ void _set_polygons(const Array &p_array);
+ Array _get_polygons() const;
+
+public:
+ enum SamplePartitionType {
+ SAMPLE_PARTITION_WATERSHED = 0,
+ SAMPLE_PARTITION_MONOTONE,
+ SAMPLE_PARTITION_LAYERS,
+ SAMPLE_PARTITION_MAX
+ };
+
+ enum ParsedGeometryType {
+ PARSED_GEOMETRY_MESH_INSTANCES = 0,
+ PARSED_GEOMETRY_STATIC_COLLIDERS,
+ PARSED_GEOMETRY_BOTH,
+ PARSED_GEOMETRY_MAX
+ };
+
+ enum SourceGeometryMode {
+ SOURCE_GEOMETRY_NAVMESH_CHILDREN = 0,
+ SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN,
+ SOURCE_GEOMETRY_GROUPS_EXPLICIT,
+ SOURCE_GEOMETRY_MAX
+ };
+
+protected:
+ float cell_size;
+ float cell_height;
+ float agent_height;
+ float agent_radius;
+ float agent_max_climb;
+ float agent_max_slope;
+ float region_min_size;
+ float region_merge_size;
+ float edge_max_length;
+ float edge_max_error;
+ float verts_per_poly;
+ float detail_sample_distance;
+ float detail_sample_max_error;
+
+ SamplePartitionType partition_type;
+ ParsedGeometryType parsed_geometry_type;
+ uint32_t collision_mask;
+
+ SourceGeometryMode source_geometry_mode;
+ StringName source_group_name;
+
+ bool filter_low_hanging_obstacles;
+ bool filter_ledge_spans;
+ bool filter_walkable_low_height_spans;
+
+public:
+ // Recast settings
+ void set_sample_partition_type(int p_value);
+ int get_sample_partition_type() const;
+
+ void set_parsed_geometry_type(int p_value);
+ int get_parsed_geometry_type() const;
+
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
+ void set_source_geometry_mode(int p_geometry_mode);
+ int get_source_geometry_mode() const;
+
+ void set_source_group_name(StringName p_group_name);
+ StringName get_source_group_name() const;
+
+ void set_cell_size(float p_value);
+ float get_cell_size() const;
+
+ void set_cell_height(float p_value);
+ float get_cell_height() const;
+
+ void set_agent_height(float p_value);
+ float get_agent_height() const;
+
+ void set_agent_radius(float p_value);
+ float get_agent_radius();
+
+ void set_agent_max_climb(float p_value);
+ float get_agent_max_climb() const;
+
+ void set_agent_max_slope(float p_value);
+ float get_agent_max_slope() const;
+
+ void set_region_min_size(float p_value);
+ float get_region_min_size() const;
+
+ void set_region_merge_size(float p_value);
+ float get_region_merge_size() const;
+
+ void set_edge_max_length(float p_value);
+ float get_edge_max_length() const;
+
+ void set_edge_max_error(float p_value);
+ float get_edge_max_error() const;
+
+ void set_verts_per_poly(float p_value);
+ float get_verts_per_poly() const;
+
+ void set_detail_sample_distance(float p_value);
+ float get_detail_sample_distance() const;
+
+ void set_detail_sample_max_error(float p_value);
+ float get_detail_sample_max_error() const;
+
+ void set_filter_low_hanging_obstacles(bool p_value);
+ bool get_filter_low_hanging_obstacles() const;
+
+ void set_filter_ledge_spans(bool p_value);
+ bool get_filter_ledge_spans() const;
+
+ void set_filter_walkable_low_height_spans(bool p_value);
+ bool get_filter_walkable_low_height_spans() const;
+
+ void create_from_mesh(const Ref<Mesh> &p_mesh);
+
+ void set_vertices(const Vector<Vector3> &p_vertices);
+ Vector<Vector3> get_vertices() const;
+
+ void add_polygon(const Vector<int> &p_polygon);
+ int get_polygon_count() const;
+ Vector<int> get_polygon(int p_idx);
+ void clear_polygons();
+
+ Ref<Mesh> get_debug_mesh();
+
+ NavigationMesh();
+};
+
+#endif // NAVIGATION_MESH_H
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 3e7d350eec..5e8bfd9387 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -35,44 +35,44 @@
#include "core/io/resource_loader.h"
#include "core/project_settings.h"
#include "scene/2d/node_2d.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/node_3d.h"
#include "scene/gui/control.h"
#include "scene/main/instance_placeholder.h"
#define PACKED_SCENE_VERSION 2
bool SceneState::can_instance() const {
-
return nodes.size() > 0;
}
Node *SceneState::instance(GenEditState p_edit_state) const {
-
// nodes where instancing failed (because something is missing)
List<Node *> stray_instances;
-#define NODE_FROM_ID(p_name, p_id) \
- Node *p_name; \
- if (p_id & FLAG_ID_IS_PATH) { \
- NodePath np = node_paths[p_id & FLAG_MASK]; \
- p_name = ret_nodes[0]->get_node_or_null(np); \
- } else { \
- ERR_FAIL_INDEX_V(p_id &FLAG_MASK, nc, NULL); \
- p_name = ret_nodes[p_id & FLAG_MASK]; \
+#define NODE_FROM_ID(p_name, p_id) \
+ Node *p_name; \
+ if (p_id & FLAG_ID_IS_PATH) { \
+ NodePath np = node_paths[p_id & FLAG_MASK]; \
+ p_name = ret_nodes[0]->get_node_or_null(np); \
+ } else { \
+ ERR_FAIL_INDEX_V(p_id &FLAG_MASK, nc, nullptr); \
+ p_name = ret_nodes[p_id & FLAG_MASK]; \
}
int nc = nodes.size();
- ERR_FAIL_COND_V(nc == 0, NULL);
+ ERR_FAIL_COND_V(nc == 0, nullptr);
- const StringName *snames = NULL;
+ const StringName *snames = nullptr;
int sname_count = names.size();
- if (sname_count)
+ if (sname_count) {
snames = &names[0];
+ }
- const Variant *props = NULL;
+ const Variant *props = nullptr;
int prop_count = variants.size();
- if (prop_count)
+ if (prop_count) {
props = &variants[0];
+ }
//Vector<Variant> properties;
@@ -82,35 +82,35 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
bool gen_node_path_cache = p_edit_state != GEN_EDIT_STATE_DISABLED && node_path_cache.empty();
- Map<Ref<Resource>, Ref<Resource> > resources_local_to_scene;
+ Map<Ref<Resource>, Ref<Resource>> resources_local_to_scene;
for (int i = 0; i < nc; i++) {
-
const NodeData &n = nd[i];
- Node *parent = NULL;
+ Node *parent = nullptr;
if (i > 0) {
-
- ERR_FAIL_COND_V_MSG(n.parent == -1, NULL, vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name]));
+ ERR_FAIL_COND_V_MSG(n.parent == -1, nullptr, vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name]));
NODE_FROM_ID(nparent, n.parent);
#ifdef DEBUG_ENABLED
if (!nparent && (n.parent & FLAG_ID_IS_PATH)) {
-
WARN_PRINT(String("Parent path '" + String(node_paths[n.parent & FLAG_MASK]) + "' for node '" + String(snames[n.name]) + "' has vanished when instancing: '" + get_path() + "'.").ascii().get_data());
}
#endif
parent = nparent;
+ } else {
+ // i == 0 is root node. Confirm that it doesn't have a parent defined.
+ ERR_FAIL_COND_V_MSG(n.parent != -1, nullptr, vformat("Invalid scene: root node %s cannot specify a parent node.", snames[n.name]));
}
- Node *node = NULL;
+ Node *node = nullptr;
if (i == 0 && base_scene_idx >= 0) {
//scene inheritance on root node
Ref<PackedScene> sdata = props[base_scene_idx];
- ERR_FAIL_COND_V(!sdata.is_valid(), NULL);
+ ERR_FAIL_COND_V(!sdata.is_valid(), nullptr);
node = sdata->instance(p_edit_state == GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE); //only main gets main edit state
- ERR_FAIL_COND_V(!node, NULL);
+ ERR_FAIL_COND_V(!node, nullptr);
if (p_edit_state != GEN_EDIT_STATE_DISABLED) {
node->set_scene_inherited_state(sdata->get_state());
}
@@ -118,14 +118,12 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
} else if (n.instance >= 0) {
//instance a scene into this node
if (n.instance & FLAG_INSTANCE_IS_PLACEHOLDER) {
-
String path = props[n.instance & FLAG_MASK];
if (disable_placeholders) {
-
Ref<PackedScene> sdata = ResourceLoader::load(path, "PackedScene");
- ERR_FAIL_COND_V(!sdata.is_valid(), NULL);
+ ERR_FAIL_COND_V(!sdata.is_valid(), nullptr);
node = sdata->instance(p_edit_state == GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE);
- ERR_FAIL_COND_V(!node, NULL);
+ ERR_FAIL_COND_V(!node, nullptr);
} else {
InstancePlaceholder *ip = memnew(InstancePlaceholder);
ip->set_instance_path(path);
@@ -134,9 +132,9 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
node->set_scene_instance_load_placeholder(true);
} else {
Ref<PackedScene> sdata = props[n.instance & FLAG_MASK];
- ERR_FAIL_COND_V(!sdata.is_valid(), NULL);
+ ERR_FAIL_COND_V(!sdata.is_valid(), nullptr);
node = sdata->instance(p_edit_state == GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE);
- ERR_FAIL_COND_V(!node, NULL);
+ ERR_FAIL_COND_V(!node, nullptr);
}
} else if (n.type == TYPE_INSTANCED) {
@@ -155,12 +153,12 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
if (!Object::cast_to<Node>(obj)) {
if (obj) {
memdelete(obj);
- obj = NULL;
+ obj = nullptr;
}
WARN_PRINT(String("Warning node of type " + snames[n.type].operator String() + " does not exist.").ascii().get_data());
if (n.parent >= 0 && n.parent < nc && ret_nodes[n.parent]) {
- if (Object::cast_to<Spatial>(ret_nodes[n.parent])) {
- obj = memnew(Spatial);
+ if (Object::cast_to<Node3D>(ret_nodes[n.parent])) {
+ obj = memnew(Node3D);
} else if (Object::cast_to<Control>(ret_nodes[n.parent])) {
obj = memnew(Control);
} else if (Object::cast_to<Node2D>(ret_nodes[n.parent])) {
@@ -187,21 +185,19 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
//properties
int nprop_count = n.properties.size();
if (nprop_count) {
-
const NodeData::Property *nprops = &n.properties[0];
for (int j = 0; j < nprop_count; j++) {
-
bool valid;
- ERR_FAIL_INDEX_V(nprops[j].name, sname_count, NULL);
- ERR_FAIL_INDEX_V(nprops[j].value, prop_count, NULL);
+ ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr);
+ ERR_FAIL_INDEX_V(nprops[j].value, prop_count, nullptr);
if (snames[nprops[j].name] == CoreStringNames::get_singleton()->_script) {
//work around to avoid old script variables from disappearing, should be the proper fix to:
//https://github.com/godotengine/godot/issues/2958
//store old state
- List<Pair<StringName, Variant> > old_state;
+ List<Pair<StringName, Variant>> old_state;
if (node->get_script_instance()) {
node->get_script_instance()->get_property_state(old_state);
}
@@ -209,11 +205,10 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
node->set(snames[nprops[j].name], props[nprops[j].value], &valid);
//restore old state for new script, if exists
- for (List<Pair<StringName, Variant> >::Element *E = old_state.front(); E; E = E->next()) {
+ for (List<Pair<StringName, Variant>>::Element *E = old_state.front(); E; E = E->next()) {
node->set(E->get().first, E->get().second);
}
} else {
-
Variant value = props[nprops[j].value];
if (value.get_type() == Variant::OBJECT) {
@@ -221,13 +216,11 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
Ref<Resource> res = value;
if (res.is_valid()) {
if (res->is_local_to_scene()) {
-
- Map<Ref<Resource>, Ref<Resource> >::Element *E = resources_local_to_scene.find(res);
+ Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.find(res);
if (E) {
value = E->get();
} else {
-
Node *base = i == 0 ? node : ret_nodes[0];
if (p_edit_state == GEN_EDIT_STATE_MAIN) {
@@ -259,8 +252,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
//groups
for (int j = 0; j < n.groups.size(); j++) {
-
- ERR_FAIL_INDEX_V(n.groups[j], sname_count, NULL);
+ ERR_FAIL_INDEX_V(n.groups[j], sname_count, nullptr);
node->add_to_group(snames[n.groups[j]], true);
}
@@ -269,8 +261,9 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
if (i > 0) {
if (parent) {
parent->_add_child_nocheck(node, snames[n.name]);
- if (n.index >= 0 && n.index < parent->get_child_count() - 1)
+ if (n.index >= 0 && n.index < parent->get_child_count() - 1) {
parent->move_child(node, n.index);
+ }
} else {
//it may be possible that an instanced scene has changed
//and the node has nowhere to go anymore
@@ -287,10 +280,10 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
if (n.owner >= 0) {
-
NODE_FROM_ID(owner, n.owner);
- if (owner)
+ if (owner) {
node->_set_owner_nocheck(owner);
+ }
}
}
@@ -302,8 +295,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
}
- for (Map<Ref<Resource>, Ref<Resource> >::Element *E = resources_local_to_scene.front(); E; E = E->next()) {
-
+ for (Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.front(); E; E = E->next()) {
E->get()->setup_local_to_scene();
}
@@ -313,25 +305,26 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
const ConnectionData *cdata = connections.ptr();
for (int i = 0; i < cc; i++) {
-
const ConnectionData &c = cdata[i];
- //ERR_FAIL_INDEX_V( c.from, nc, NULL );
- //ERR_FAIL_INDEX_V( c.to, nc, NULL );
+ //ERR_FAIL_INDEX_V( c.from, nc, nullptr );
+ //ERR_FAIL_INDEX_V( c.to, nc, nullptr );
NODE_FROM_ID(cfrom, c.from);
NODE_FROM_ID(cto, c.to);
- if (!cfrom || !cto)
+ if (!cfrom || !cto) {
continue;
+ }
Vector<Variant> binds;
if (c.binds.size()) {
binds.resize(c.binds.size());
- for (int j = 0; j < c.binds.size(); j++)
+ for (int j = 0; j < c.binds.size(); j++) {
binds.write[j] = props[c.binds[j]];
+ }
}
- cfrom->connect(snames[c.signal], cto, snames[c.method], binds, CONNECT_PERSIST | c.flags);
+ cfrom->connect(snames[c.signal], Callable(cto, snames[c.method]), binds, CONNECT_PERSIST | c.flags);
}
//Node *s = ret_nodes[0];
@@ -353,9 +346,9 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
static int _nm_get_string(const String &p_string, Map<StringName, int> &name_map) {
-
- if (name_map.has(p_string))
+ if (name_map.has(p_string)) {
return name_map[p_string];
+ }
int idx = name_map.size();
name_map[p_string] = idx;
@@ -363,9 +356,9 @@ static int _nm_get_string(const String &p_string, Map<StringName, int> &name_map
}
static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map) {
-
- if (variant_map.has(p_variant))
+ if (variant_map.has(p_variant)) {
return variant_map[p_variant];
+ }
int idx = variant_map.size();
variant_map[p_variant] = idx;
@@ -373,20 +366,21 @@ static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int, Varia
}
Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, Map<Node *, int> &node_map, Map<Node *, int> &nodepath_map) {
-
// this function handles all the work related to properly packing scenes, be it
// instanced or inherited.
// given the complexity of this process, an attempt will be made to properly
// document it. if you fail to understand something, please ask!
//discard nodes that do not belong to be processed
- if (p_node != p_owner && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner()))
+ if (p_node != p_owner && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner())) {
return OK;
+ }
// save the child instanced scenes that are chosen as editable, so they can be restored
// upon load back
- if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node))
+ if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node)) {
editable_instances.push_back(p_owner->get_path_to(p_node));
+ }
NodeData nd;
@@ -418,9 +412,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
Node *n = p_node;
while (n) {
-
if (n == p_owner) {
-
Ref<SceneState> state = n->get_scene_inherited_state();
if (state.is_valid()) {
int node = state->find_node_by_path(n->get_path_to(p_node));
@@ -435,7 +427,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
if (p_node->get_filename() != String() && p_node->get_owner() == p_owner && instanced_by_owner) {
-
if (p_node->get_scene_instance_load_placeholder()) {
//it's a placeholder, use the placeholder path
nd.instance = _vm_get_variant(p_node->get_filename(), variant_map);
@@ -450,7 +441,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
nd.instance = _vm_get_variant(instance, variant_map);
}
}
- n = NULL;
+ n = nullptr;
} else {
if (n->get_filename() != String()) {
//is an instance
@@ -479,7 +470,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
StringName type = p_node->get_class();
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
@@ -530,17 +520,16 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
if (exists) {
-
//check if already exists and did not change
- if (value.get_type() == Variant::REAL && original.get_type() == Variant::REAL) {
+ if (value.get_type() == Variant::FLOAT && original.get_type() == Variant::FLOAT) {
//this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
float a = value;
float b = original;
- if (Math::is_equal_approx(a, b))
+ if (Math::is_equal_approx(a, b)) {
continue;
+ }
} else if (bool(Variant::evaluate(Variant::OP_EQUAL, value, original))) {
-
continue;
}
}
@@ -552,7 +541,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
} else {
-
if (isdefault) {
//it's the default value, no point in saving it
continue;
@@ -573,8 +561,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
for (List<Node::GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
Node::GroupInfo &gi = E->get();
- if (!gi.persistent)
+ if (!gi.persistent) {
continue;
+ }
/*
if (instance_state_node>=0 && instance_state->is_node_in_group(instance_state_node,gi.name))
continue; //group was instanced, don't add here
@@ -590,8 +579,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
}
- if (skip)
+ if (skip) {
continue;
+ }
nd.groups.push_back(_nm_get_string(gi.name, name_map));
}
@@ -608,7 +598,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
//part of saved scene
nd.owner = 0;
} else {
-
nd.owner = -1;
}
@@ -637,14 +626,12 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
int parent_node = NO_PARENT_SAVED;
if (save_node) {
-
//don't save the node if nothing and subscene
node_map[p_node] = idx;
//ok validate parent node
if (p_parent_idx == NO_PARENT_SAVED) {
-
int sidx;
if (nodepath_map.has(p_node->get_parent())) {
sidx = nodepath_map[p_node->get_parent()];
@@ -663,20 +650,20 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *c = p_node->get_child(i);
Error err = _parse_node(p_owner, c, parent_node, name_map, variant_map, node_map, nodepath_map);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
}
Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, Map<Node *, int> &node_map, Map<Node *, int> &nodepath_map) {
-
- if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner()))
+ if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner())) {
return OK;
+ }
List<MethodInfo> _signals;
p_node->get_signal_list(&_signals);
@@ -686,23 +673,22 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
//NodeData &nd = nodes[node_map[p_node]];
for (List<MethodInfo>::Element *E = _signals.front(); E; E = E->next()) {
-
List<Node::Connection> conns;
p_node->get_signal_connection_list(E->get().name, &conns);
conns.sort();
for (List<Node::Connection>::Element *F = conns.front(); F; F = F->next()) {
-
const Node::Connection &c = F->get();
- if (!(c.flags & CONNECT_PERSIST)) //only persistent connections get saved
+ if (!(c.flags & CONNECT_PERSIST)) { //only persistent connections get saved
continue;
+ }
// only connections that originate or end into main saved scene are saved
// everything else is discarded
- Node *target = Object::cast_to<Node>(c.target);
+ Node *target = Object::cast_to<Node>(c.callable.get_object());
if (!target) {
continue;
@@ -721,29 +707,29 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
//go through ownership chain to see if this exists
while (common_parent) {
-
Ref<SceneState> ps;
- if (common_parent == p_owner)
+ if (common_parent == p_owner) {
ps = common_parent->get_scene_inherited_state();
- else
+ } else {
ps = common_parent->get_scene_instance_state();
+ }
if (ps.is_valid()) {
-
NodePath signal_from = common_parent->get_path_to(p_node);
NodePath signal_to = common_parent->get_path_to(target);
- if (ps->has_connection(signal_from, c.signal, signal_to, c.method)) {
+ if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, c.callable.get_method())) {
exists = true;
break;
}
}
- if (common_parent == p_owner)
+ if (common_parent == p_owner) {
break;
- else
+ } else {
common_parent = common_parent->get_owner();
+ }
}
if (exists) { //already exists (comes from instance or inheritance), so don't save
@@ -756,9 +742,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
bool exists2 = false;
while (nl) {
-
if (nl == p_owner) {
-
Ref<SceneState> state = nl->get_scene_inherited_state();
if (state.is_valid()) {
int from_node = state->find_node_by_path(nl->get_path_to(p_node));
@@ -766,14 +750,14 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
if (from_node >= 0 && to_node >= 0) {
//this one has state for this node, save
- if (state->is_connection(from_node, c.signal, to_node, c.method)) {
+ if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) {
exists2 = true;
break;
}
}
}
- nl = NULL;
+ nl = nullptr;
} else {
if (nl->get_filename() != String()) {
//is an instance
@@ -784,7 +768,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
if (from_node >= 0 && to_node >= 0) {
//this one has state for this node, save
- if (state->is_connection(from_node, c.signal, to_node, c.method)) {
+ if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) {
exists2 = true;
break;
}
@@ -831,11 +815,10 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
ConnectionData cd;
cd.from = src_id;
cd.to = target_id;
- cd.method = _nm_get_string(c.method, name_map);
- cd.signal = _nm_get_string(c.signal, name_map);
+ cd.method = _nm_get_string(c.callable.get_method(), name_map);
+ cd.signal = _nm_get_string(c.signal.get_name(), name_map);
cd.flags = c.flags;
for (int i = 0; i < c.binds.size(); i++) {
-
cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map));
}
connections.push_back(cd);
@@ -843,11 +826,11 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *c = p_node->get_child(i);
Error err = _parse_connections(p_owner, c, name_map, variant_map, node_map, nodepath_map);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
@@ -865,17 +848,16 @@ Error SceneState::pack(Node *p_scene) {
Map<Node *, int> node_map;
Map<Node *, int> nodepath_map;
- //if using scene inheritance, pack the scene it inherits from
+ // If using scene inheritance, pack the scene it inherits from.
if (scene->get_scene_inherited_state().is_valid()) {
String path = scene->get_scene_inherited_state()->get_path();
Ref<PackedScene> instance = ResourceLoader::load(path);
if (instance.is_valid()) {
-
base_scene_idx = _vm_get_variant(instance, variant_map);
}
}
- //instanced, only direct sub-scnes are supported of course
+ // Instanced, only direct sub-scenes are supported of course.
Error err = _parse_node(scene, scene, -1, name_map, variant_map, node_map, nodepath_map);
if (err) {
clear();
@@ -891,21 +873,18 @@ Error SceneState::pack(Node *p_scene) {
names.resize(name_map.size());
for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) {
-
names.write[E->get()] = E->key();
}
variants.resize(variant_map.size());
- const Variant *K = NULL;
+ const Variant *K = nullptr;
while ((K = variant_map.next(K))) {
-
int idx = variant_map[*K];
variants.write[idx] = *K;
}
node_paths.resize(nodepath_map.size());
for (Map<Node *, int>::Element *E = nodepath_map.front(); E; E = E->next()) {
-
node_paths.write[E->get()] = scene->get_path_to(E->key());
}
@@ -913,17 +892,14 @@ Error SceneState::pack(Node *p_scene) {
}
void SceneState::set_path(const String &p_path) {
-
path = p_path;
}
String SceneState::get_path() const {
-
return path;
}
void SceneState::clear() {
-
names.clear();
variants.clear();
nodes.clear();
@@ -935,9 +911,7 @@ void SceneState::clear() {
}
Ref<SceneState> SceneState::_get_base_scene_state() const {
-
if (base_scene_idx >= 0) {
-
Ref<PackedScene> ps = variants[base_scene_idx];
if (ps.is_valid()) {
return ps->get_state();
@@ -948,7 +922,6 @@ Ref<SceneState> SceneState::_get_base_scene_state() const {
}
int SceneState::find_node_by_path(const NodePath &p_node) const {
-
if (!node_path_cache.has(p_node)) {
if (_get_base_scene_state().is_valid()) {
int idx = _get_base_scene_state()->find_node_by_path(p_node);
@@ -980,7 +953,6 @@ int SceneState::find_node_by_path(const NodePath &p_node) const {
}
int SceneState::_find_base_scene_node_remap_key(int p_idx) const {
-
for (Map<int, int>::Element *E = base_scene_node_remap.front(); E; E = E->next()) {
if (E->value() == p_idx) {
return E->key();
@@ -990,7 +962,6 @@ int SceneState::_find_base_scene_node_remap_key(int p_idx) const {
}
Variant SceneState::get_property_value(int p_node, const StringName &p_property, bool &found) const {
-
found = false;
ERR_FAIL_COND_V(p_node < 0, Variant());
@@ -1019,14 +990,14 @@ Variant SceneState::get_property_value(int p_node, const StringName &p_property,
}
bool SceneState::is_node_in_group(int p_node, const StringName &p_group) const {
-
ERR_FAIL_COND_V(p_node < 0, false);
if (p_node < nodes.size()) {
const StringName *namep = names.ptr();
for (int i = 0; i < nodes[p_node].groups.size(); i++) {
- if (namep[nodes[p_node].groups[i]] == p_group)
+ if (namep[nodes[p_node].groups[i]] == p_group) {
return true;
+ }
}
}
@@ -1040,17 +1011,14 @@ bool SceneState::is_node_in_group(int p_node, const StringName &p_group) const {
bool SceneState::disable_placeholders = false;
void SceneState::set_disable_placeholders(bool p_disable) {
-
disable_placeholders = p_disable;
}
bool SceneState::is_connection(int p_node, const StringName &p_signal, int p_to_node, const StringName &p_to_method) const {
-
ERR_FAIL_COND_V(p_node < 0, false);
ERR_FAIL_COND_V(p_to_node < 0, false);
if (p_node < nodes.size() && p_to_node < nodes.size()) {
-
int signal_idx = -1;
int method_idx = -1;
for (int i = 0; i < names.size(); i++) {
@@ -1065,9 +1033,7 @@ bool SceneState::is_connection(int p_node, const StringName &p_signal, int p_to_
//signal and method strings are stored..
for (int i = 0; i < connections.size(); i++) {
-
if (connections[i].from == p_node && connections[i].to == p_to_node && connections[i].signal == signal_idx && connections[i].method == method_idx) {
-
return true;
}
}
@@ -1082,7 +1048,6 @@ bool SceneState::is_connection(int p_node, const StringName &p_signal, int p_to_
}
void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
-
ERR_FAIL_COND(!p_dictionary.has("names"));
ERR_FAIL_COND(!p_dictionary.has("variants"));
ERR_FAIL_COND(!p_dictionary.has("node_count"));
@@ -1092,27 +1057,28 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
//ERR_FAIL_COND( !p_dictionary.has("path"));
int version = 1;
- if (p_dictionary.has("version"))
+ if (p_dictionary.has("version")) {
version = p_dictionary["version"];
+ }
ERR_FAIL_COND_MSG(version > PACKED_SCENE_VERSION, "Save format version too new.");
const int node_count = p_dictionary["node_count"];
- const PoolVector<int> snodes = p_dictionary["nodes"];
+ const Vector<int> snodes = p_dictionary["nodes"];
ERR_FAIL_COND(snodes.size() < node_count);
const int conn_count = p_dictionary["conn_count"];
- const PoolVector<int> sconns = p_dictionary["conns"];
+ const Vector<int> sconns = p_dictionary["conns"];
ERR_FAIL_COND(sconns.size() < conn_count);
- PoolVector<String> snames = p_dictionary["names"];
+ Vector<String> snames = p_dictionary["names"];
if (snames.size()) {
-
int namecount = snames.size();
names.resize(namecount);
- PoolVector<String>::Read r = snames.read();
- for (int i = 0; i < names.size(); i++)
+ const String *r = snames.ptr();
+ for (int i = 0; i < names.size(); i++) {
names.write[i] = r[i];
+ }
}
Array svariants = p_dictionary["variants"];
@@ -1121,7 +1087,6 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
int varcount = svariants.size();
variants.resize(varcount);
for (int i = 0; i < varcount; i++) {
-
variants.write[i] = svariants[i];
}
@@ -1131,7 +1096,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
nodes.resize(node_count);
if (node_count) {
- PoolVector<int>::Read r = snodes.read();
+ const int *r = snodes.ptr();
int idx = 0;
for (int i = 0; i < node_count; i++) {
NodeData &nd = nodes.write[i];
@@ -1145,13 +1110,11 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
nd.instance = r[idx++];
nd.properties.resize(r[idx++]);
for (int j = 0; j < nd.properties.size(); j++) {
-
nd.properties.write[j].name = r[idx++];
nd.properties.write[j].value = r[idx++];
}
nd.groups.resize(r[idx++]);
for (int j = 0; j < nd.groups.size(); j++) {
-
nd.groups.write[j] = r[idx++];
}
}
@@ -1159,7 +1122,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
connections.resize(conn_count);
if (conn_count) {
- PoolVector<int>::Read r = sconns.read();
+ const int *r = sconns.ptr();
int idx = 0;
for (int i = 0; i < conn_count; i++) {
ConnectionData &cd = connections.write[i];
@@ -1171,7 +1134,6 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
cd.binds.resize(r[idx++]);
for (int j = 0; j < cd.binds.size(); j++) {
-
cd.binds.write[j] = r[idx++];
}
}
@@ -1204,16 +1166,15 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
}
Dictionary SceneState::get_bundled_scene() const {
-
- PoolVector<String> rnames;
+ Vector<String> rnames;
rnames.resize(names.size());
if (names.size()) {
+ String *r = rnames.ptrw();
- PoolVector<String>::Write r = rnames.write();
-
- for (int i = 0; i < names.size(); i++)
+ for (int i = 0; i < names.size(); i++) {
r[i] = names[i];
+ }
}
Dictionary d;
@@ -1224,7 +1185,6 @@ Dictionary SceneState::get_bundled_scene() const {
d["node_count"] = nodes.size();
for (int i = 0; i < nodes.size(); i++) {
-
const NodeData &nd = nodes[i];
rnodes.push_back(nd.parent);
rnodes.push_back(nd.owner);
@@ -1237,13 +1197,11 @@ Dictionary SceneState::get_bundled_scene() const {
rnodes.push_back(nd.instance);
rnodes.push_back(nd.properties.size());
for (int j = 0; j < nd.properties.size(); j++) {
-
rnodes.push_back(nd.properties[j].name);
rnodes.push_back(nd.properties[j].value);
}
rnodes.push_back(nd.groups.size());
for (int j = 0; j < nd.groups.size(); j++) {
-
rnodes.push_back(nd.groups[j]);
}
}
@@ -1254,7 +1212,6 @@ Dictionary SceneState::get_bundled_scene() const {
d["conn_count"] = connections.size();
for (int i = 0; i < connections.size(); i++) {
-
const ConnectionData &cd = connections[i];
rconns.push_back(cd.from);
rconns.push_back(cd.to);
@@ -1262,8 +1219,9 @@ Dictionary SceneState::get_bundled_scene() const {
rconns.push_back(cd.method);
rconns.push_back(cd.flags);
rconns.push_back(cd.binds.size());
- for (int j = 0; j < cd.binds.size(); j++)
+ for (int j = 0; j < cd.binds.size(); j++) {
rconns.push_back(cd.binds[j]);
+ }
}
d["conns"] = rconns;
@@ -1291,20 +1249,18 @@ Dictionary SceneState::get_bundled_scene() const {
}
int SceneState::get_node_count() const {
-
return nodes.size();
}
StringName SceneState::get_node_type(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
- if (nodes[p_idx].type == TYPE_INSTANCED)
+ if (nodes[p_idx].type == TYPE_INSTANCED) {
return StringName();
+ }
return names[nodes[p_idx].type];
}
StringName SceneState::get_node_name(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
return names[nodes[p_idx].name];
}
@@ -1315,7 +1271,6 @@ int SceneState::get_node_index(int p_idx) const {
}
bool SceneState::is_node_instance_placeholder(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), false);
return nodes[p_idx].instance >= 0 && (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER);
@@ -1325,12 +1280,12 @@ Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, nodes.size(), Ref<PackedScene>());
if (nodes[p_idx].instance >= 0) {
- if (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER)
+ if (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER) {
return Ref<PackedScene>();
- else
+ } else {
return variants[nodes[p_idx].instance & FLAG_MASK];
+ }
} else if (nodes[p_idx].parent < 0 || nodes[p_idx].parent == NO_PARENT_SAVED) {
-
if (base_scene_idx >= 0) {
return variants[base_scene_idx];
}
@@ -1340,7 +1295,6 @@ Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
}
String SceneState::get_node_instance_placeholder(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), String());
if (nodes[p_idx].instance >= 0 && (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER)) {
@@ -1360,7 +1314,6 @@ Vector<StringName> SceneState::get_node_groups(int p_idx) const {
}
NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), NodePath());
if (nodes[p_idx].parent < 0 || nodes[p_idx].parent == NO_PARENT_SAVED) {
@@ -1376,7 +1329,6 @@ NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
int nidx = p_idx;
while (true) {
if (nodes[nidx].parent == NO_PARENT_SAVED || nodes[nidx].parent < 0) {
-
sub_path.insert(0, ".");
break;
}
@@ -1405,15 +1357,16 @@ NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
}
int SceneState::get_node_property_count(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), -1);
return nodes[p_idx].properties.size();
}
+
StringName SceneState::get_node_property_name(int p_idx, int p_prop) const {
ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
ERR_FAIL_INDEX_V(p_prop, nodes[p_idx].properties.size(), StringName());
return names[nodes[p_idx].properties[p_prop].name];
}
+
Variant SceneState::get_node_property_value(int p_idx, int p_prop) const {
ERR_FAIL_INDEX_V(p_idx, nodes.size(), Variant());
ERR_FAIL_INDEX_V(p_prop, nodes[p_idx].properties.size(), Variant());
@@ -1422,10 +1375,10 @@ Variant SceneState::get_node_property_value(int p_idx, int p_prop) const {
}
NodePath SceneState::get_node_owner_path(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), NodePath());
- if (nodes[p_idx].owner < 0 || nodes[p_idx].owner == NO_PARENT_SAVED)
+ if (nodes[p_idx].owner < 0 || nodes[p_idx].owner == NO_PARENT_SAVED) {
return NodePath(); //root likely
+ }
if (nodes[p_idx].owner & FLAG_ID_IS_PATH) {
return node_paths[nodes[p_idx].owner & FLAG_MASK];
} else {
@@ -1434,11 +1387,10 @@ NodePath SceneState::get_node_owner_path(int p_idx) const {
}
int SceneState::get_connection_count() const {
-
return connections.size();
}
-NodePath SceneState::get_connection_source(int p_idx) const {
+NodePath SceneState::get_connection_source(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, connections.size(), NodePath());
if (connections[p_idx].from & FLAG_ID_IS_PATH) {
return node_paths[connections[p_idx].from & FLAG_MASK];
@@ -1448,12 +1400,11 @@ NodePath SceneState::get_connection_source(int p_idx) const {
}
StringName SceneState::get_connection_signal(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, connections.size(), StringName());
return names[connections[p_idx].signal];
}
-NodePath SceneState::get_connection_target(int p_idx) const {
+NodePath SceneState::get_connection_target(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, connections.size(), NodePath());
if (connections[p_idx].to & FLAG_ID_IS_PATH) {
return node_paths[connections[p_idx].to & FLAG_MASK];
@@ -1461,20 +1412,18 @@ NodePath SceneState::get_connection_target(int p_idx) const {
return get_node_path(connections[p_idx].to & FLAG_MASK);
}
}
-StringName SceneState::get_connection_method(int p_idx) const {
+StringName SceneState::get_connection_method(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, connections.size(), StringName());
return names[connections[p_idx].method];
}
int SceneState::get_connection_flags(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, connections.size(), -1);
return connections[p_idx].flags;
}
Array SceneState::get_connection_binds(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, connections.size(), Array());
Array binds;
for (int i = 0; i < connections[p_idx].binds.size(); i++) {
@@ -1484,7 +1433,6 @@ Array SceneState::get_connection_binds(int p_idx) const {
}
bool SceneState::has_connection(const NodePath &p_node_from, const StringName &p_signal, const NodePath &p_node_to, const StringName &p_method) {
-
// this method cannot be const because of this
Ref<SceneState> ss = this;
@@ -1525,37 +1473,35 @@ bool SceneState::has_connection(const NodePath &p_node_from, const StringName &p
Vector<NodePath> SceneState::get_editable_instances() const {
return editable_instances;
}
+
//add
int SceneState::add_name(const StringName &p_name) {
-
names.push_back(p_name);
return names.size() - 1;
}
int SceneState::find_name(const StringName &p_name) const {
-
for (int i = 0; i < names.size(); i++) {
- if (names[i] == p_name)
+ if (names[i] == p_name) {
return i;
+ }
}
return -1;
}
int SceneState::add_value(const Variant &p_value) {
-
variants.push_back(p_value);
return variants.size() - 1;
}
int SceneState::add_node_path(const NodePath &p_path) {
-
node_paths.push_back(p_path);
return (node_paths.size() - 1) | FLAG_ID_IS_PATH;
}
-int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance, int p_index) {
+int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance, int p_index) {
NodeData nd;
nd.parent = p_parent;
nd.owner = p_owner;
@@ -1568,8 +1514,8 @@ int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int
return nodes.size() - 1;
}
-void SceneState::add_node_property(int p_node, int p_name, int p_value) {
+void SceneState::add_node_property(int p_node, int p_name, int p_value) {
ERR_FAIL_INDEX(p_node, nodes.size());
ERR_FAIL_INDEX(p_name, names.size());
ERR_FAIL_INDEX(p_value, variants.size());
@@ -1579,19 +1525,19 @@ void SceneState::add_node_property(int p_node, int p_name, int p_value) {
prop.value = p_value;
nodes.write[p_node].properties.push_back(prop);
}
-void SceneState::add_node_group(int p_node, int p_group) {
+void SceneState::add_node_group(int p_node, int p_group) {
ERR_FAIL_INDEX(p_node, nodes.size());
ERR_FAIL_INDEX(p_group, names.size());
nodes.write[p_node].groups.push_back(p_group);
}
-void SceneState::set_base_scene(int p_idx) {
+void SceneState::set_base_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, variants.size());
base_scene_idx = p_idx;
}
-void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) {
+void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) {
ERR_FAIL_INDEX(p_signal, names.size());
ERR_FAIL_INDEX(p_method, names.size());
@@ -1607,24 +1553,23 @@ void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method
c.binds = p_binds;
connections.push_back(c);
}
-void SceneState::add_editable_instance(const NodePath &p_path) {
+void SceneState::add_editable_instance(const NodePath &p_path) {
editable_instances.push_back(p_path);
}
-PoolVector<String> SceneState::_get_node_groups(int p_idx) const {
-
+Vector<String> SceneState::_get_node_groups(int p_idx) const {
Vector<StringName> groups = get_node_groups(p_idx);
- PoolVector<String> ret;
+ Vector<String> ret;
- for (int i = 0; i < groups.size(); i++)
+ for (int i = 0; i < groups.size(); i++) {
ret.push_back(groups[i]);
+ }
return ret;
}
void SceneState::_bind_methods() {
-
//unbuild API
ClassDB::bind_method(D_METHOD("get_node_count"), &SceneState::get_node_count);
@@ -1654,7 +1599,6 @@ void SceneState::_bind_methods() {
}
SceneState::SceneState() {
-
base_scene_idx = -1;
last_modified_time = 0;
}
@@ -1662,46 +1606,42 @@ SceneState::SceneState() {
////////////////
void PackedScene::_set_bundled_scene(const Dictionary &p_scene) {
-
state->set_bundled_scene(p_scene);
}
Dictionary PackedScene::_get_bundled_scene() const {
-
return state->get_bundled_scene();
}
Error PackedScene::pack(Node *p_scene) {
-
return state->pack(p_scene);
}
void PackedScene::clear() {
-
state->clear();
}
bool PackedScene::can_instance() const {
-
return state->can_instance();
}
Node *PackedScene::instance(GenEditState p_edit_state) const {
-
#ifndef TOOLS_ENABLED
- ERR_FAIL_COND_V_MSG(p_edit_state != GEN_EDIT_STATE_DISABLED, NULL, "Edit state is only for editors, does not work without tools compiled.");
+ ERR_FAIL_COND_V_MSG(p_edit_state != GEN_EDIT_STATE_DISABLED, nullptr, "Edit state is only for editors, does not work without tools compiled.");
#endif
Node *s = state->instance((SceneState::GenEditState)p_edit_state);
- if (!s)
- return NULL;
+ if (!s) {
+ return nullptr;
+ }
if (p_edit_state != GEN_EDIT_STATE_DISABLED) {
s->set_scene_instance_state(state);
}
- if (get_path() != "" && get_path().find("::") == -1)
+ if (get_path() != "" && get_path().find("::") == -1) {
s->set_filename(get_path());
+ }
s->notification(Node::NOTIFICATION_INSTANCED);
@@ -1709,7 +1649,6 @@ Node *PackedScene::instance(GenEditState p_edit_state) const {
}
void PackedScene::replace_state(Ref<SceneState> p_by) {
-
state = p_by;
state->set_path(get_path());
#ifdef TOOLS_ENABLED
@@ -1718,7 +1657,6 @@ void PackedScene::replace_state(Ref<SceneState> p_by) {
}
void PackedScene::recreate_state() {
-
state = Ref<SceneState>(memnew(SceneState));
state->set_path(get_path());
#ifdef TOOLS_ENABLED
@@ -1727,18 +1665,15 @@ void PackedScene::recreate_state() {
}
Ref<SceneState> PackedScene::get_state() {
-
return state;
}
void PackedScene::set_path(const String &p_path, bool p_take_over) {
-
state->set_path(p_path);
Resource::set_path(p_path, p_take_over);
}
void PackedScene::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("pack", "path"), &PackedScene::pack);
ClassDB::bind_method(D_METHOD("instance", "edit_state"), &PackedScene::instance, DEFVAL(GEN_EDIT_STATE_DISABLED));
ClassDB::bind_method(D_METHOD("can_instance"), &PackedScene::can_instance);
@@ -1754,6 +1689,5 @@ void PackedScene::_bind_methods() {
}
PackedScene::PackedScene() {
-
state = Ref<SceneState>(memnew(SceneState));
}
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index b4966e2528..004758afa5 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -35,7 +35,6 @@
#include "scene/main/node.h"
class SceneState : public Reference {
-
GDCLASS(SceneState, Reference);
Vector<StringName> names;
@@ -54,7 +53,6 @@ class SceneState : public Reference {
};
struct NodeData {
-
int parent;
int owner;
int type;
@@ -63,7 +61,6 @@ class SceneState : public Reference {
int index;
struct Property {
-
int name;
int value;
};
@@ -81,7 +78,6 @@ class SceneState : public Reference {
Vector<NodeData> nodes;
struct ConnectionData {
-
int from;
int to;
int signal;
@@ -103,7 +99,7 @@ class SceneState : public Reference {
static bool disable_placeholders;
- PoolVector<String> _get_node_groups(int p_idx) const;
+ Vector<String> _get_node_groups(int p_idx) const;
int _find_base_scene_node_remap_key(int p_idx) const;
@@ -195,7 +191,6 @@ public:
VARIANT_ENUM_CAST(SceneState::GenEditState)
class PackedScene : public Resource {
-
GDCLASS(PackedScene, Resource);
RES_BASE_EXTENSION("scn");
@@ -205,7 +200,7 @@ class PackedScene : public Resource {
Dictionary _get_bundled_scene() const;
protected:
- virtual bool editor_can_reload_from_file() { return false; } // this is handled by editor better
+ virtual bool editor_can_reload_from_file() override { return false; } // this is handled by editor better
static void _bind_methods();
public:
@@ -225,9 +220,9 @@ public:
void recreate_state();
void replace_state(Ref<SceneState> p_by);
- virtual void set_path(const String &p_path, bool p_take_over = false);
+ virtual void set_path(const String &p_path, bool p_take_over = false) override;
#ifdef TOOLS_ENABLED
- virtual void set_last_modified_time(uint64_t p_time) { state->set_last_modified_time(p_time); }
+ virtual void set_last_modified_time(uint64_t p_time) override { state->set_last_modified_time(p_time); }
#endif
Ref<SceneState> get_state();
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 412b5c259c..4bbfa8965a 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -30,17 +30,12 @@
#include "particles_material.h"
-Mutex *ParticlesMaterial::material_mutex = NULL;
-SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = NULL;
+Mutex ParticlesMaterial::material_mutex;
+SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = nullptr;
Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map;
-ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL;
+ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = nullptr;
void ParticlesMaterial::init_shaders() {
-
-#ifndef NO_THREADS
- material_mutex = Mutex::create();
-#endif
-
dirty_materials = memnew(SelfList<ParticlesMaterial>::List);
shader_names = memnew(ShaderNames);
@@ -96,40 +91,35 @@ void ParticlesMaterial::init_shaders() {
shader_names->emission_texture_normal = "emission_texture_normal";
shader_names->emission_texture_color = "emission_texture_color";
- shader_names->trail_divisor = "trail_divisor";
- shader_names->trail_size_modifier = "trail_size_modifier";
- shader_names->trail_color_modifier = "trail_color_modifier";
-
shader_names->gravity = "gravity";
shader_names->lifetime_randomness = "lifetime_randomness";
+
+ shader_names->sub_emitter_frequency = "sub_emitter_frequency";
+ shader_names->sub_emitter_amount_at_end = "sub_emitter_amount_at_end";
+ shader_names->sub_emitter_keep_velocity = "sub_emitter_keep_velocity";
}
void ParticlesMaterial::finish_shaders() {
-
-#ifndef NO_THREADS
- memdelete(material_mutex);
-#endif
-
memdelete(dirty_materials);
- dirty_materials = NULL;
+ dirty_materials = nullptr;
memdelete(shader_names);
}
void ParticlesMaterial::_update_shader() {
-
dirty_materials->remove(&element);
MaterialKey mk = _compute_key();
- if (mk.key == current_key.key)
+ if (mk.key == current_key.key) {
return; //no update required in the end
+ }
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
if (shader_map[current_key].users == 0) {
//deallocate shader, as it's no longer in use
- VS::get_singleton()->free(shader_map[current_key].shader);
+ RS::get_singleton()->free(shader_map[current_key].shader);
shader_map.erase(current_key);
}
}
@@ -137,8 +127,7 @@ void ParticlesMaterial::_update_shader() {
current_key = mk;
if (shader_map.has(mk)) {
-
- VS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
+ RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
shader_map[mk].users++;
return;
}
@@ -189,7 +178,7 @@ void ParticlesMaterial::_update_shader() {
} break;
case EMISSION_SHAPE_DIRECTED_POINTS: {
code += "uniform sampler2D emission_texture_normal : hint_black;\n";
- FALLTHROUGH;
+ [[fallthrough]];
}
case EMISSION_SHAPE_POINTS: {
code += "uniform sampler2D emission_texture_points : hint_black;\n";
@@ -203,46 +192,59 @@ void ParticlesMaterial::_update_shader() {
}
}
- code += "uniform vec4 color_value : hint_color;\n";
+ if (sub_emitter_mode != SUB_EMITTER_DISABLED) {
+ if (sub_emitter_mode == SUB_EMITTER_CONSTANT) {
+ code += "uniform float sub_emitter_frequency;\n";
+ }
+ if (sub_emitter_mode == SUB_EMITTER_AT_END) {
+ code += "uniform int sub_emitter_amount_at_end;\n";
+ }
+ code += "uniform bool sub_emitter_keep_velocity;\n";
+ }
- code += "uniform int trail_divisor;\n";
+ code += "uniform vec4 color_value : hint_color;\n";
code += "uniform vec3 gravity;\n";
- if (color_ramp.is_valid())
+ if (color_ramp.is_valid()) {
code += "uniform sampler2D color_ramp;\n";
+ }
- if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += "uniform sampler2D linear_velocity_texture;\n";
- if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
+ }
+ if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
code += "uniform sampler2D orbit_velocity_texture;\n";
- if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
+ }
+ if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
code += "uniform sampler2D angular_velocity_texture;\n";
- if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid())
+ }
+ if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
code += "uniform sampler2D linear_accel_texture;\n";
- if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid())
+ }
+ if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
code += "uniform sampler2D radial_accel_texture;\n";
- if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid())
+ }
+ if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
code += "uniform sampler2D tangent_accel_texture;\n";
- if (tex_parameters[PARAM_DAMPING].is_valid())
+ }
+ if (tex_parameters[PARAM_DAMPING].is_valid()) {
code += "uniform sampler2D damping_texture;\n";
- if (tex_parameters[PARAM_ANGLE].is_valid())
+ }
+ if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += "uniform sampler2D angle_texture;\n";
- if (tex_parameters[PARAM_SCALE].is_valid())
+ }
+ if (tex_parameters[PARAM_SCALE].is_valid()) {
code += "uniform sampler2D scale_texture;\n";
- if (tex_parameters[PARAM_HUE_VARIATION].is_valid())
+ }
+ if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
code += "uniform sampler2D hue_variation_texture;\n";
- if (tex_parameters[PARAM_ANIM_SPEED].is_valid())
+ }
+ if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
code += "uniform sampler2D anim_speed_texture;\n";
- if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
- code += "uniform sampler2D anim_offset_texture;\n";
-
- if (trail_size_modifier.is_valid()) {
- code += "uniform sampler2D trail_size_modifier;\n";
}
-
- if (trail_color_modifier.is_valid()) {
- code += "uniform sampler2D trail_color_modifier;\n";
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
+ code += "uniform sampler2D anim_offset_texture;\n";
}
//need a random function
@@ -275,8 +277,8 @@ void ParticlesMaterial::_update_shader() {
code += "}\n";
code += "\n";
- code += "void vertex() {\n";
- code += " uint base_number = NUMBER / uint(trail_divisor);\n";
+ code += "void compute() {\n";
+ code += " uint base_number = NUMBER;\n";
code += " uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);\n";
code += " float angle_rand = rand_from_seed(alt_seed);\n";
code += " float scale_rand = rand_from_seed(alt_seed);\n";
@@ -291,46 +293,50 @@ void ParticlesMaterial::_update_shader() {
code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n";
code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n";
}
- code += " bool restart = false;\n";
- code += " if (CUSTOM.y > CUSTOM.w) {\n";
- code += " restart = true;\n";
- code += " }\n\n";
- code += " if (RESTART || restart) {\n";
-
- if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
- code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n";
- else
- code += " float tex_linear_velocity = 0.0;\n";
+ code += " if (RESTART) {\n";
- if (tex_parameters[PARAM_ANGLE].is_valid())
+ if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += " float tex_angle = textureLod(angle_texture, vec2(0.0, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_angle = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(0.0, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_anim_offset = 0.0;\n";
+ }
code += " float spread_rad = spread * degree_to_rad;\n";
- if (flags[FLAG_DISABLE_Z]) {
+ code += " if (RESTART_VELOCITY) {\n";
+
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
+ code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n";
+ } else {
+ code += " float tex_linear_velocity = 0.0;\n";
+ }
- code += " float angle1_rad = atan(direction.y, direction.x) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
- code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n";
- code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ if (flags[FLAG_DISABLE_Z]) {
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
+ code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n";
+ code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n";
+ code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
} else {
//initiate velocity spread in 3D
- code += " float angle1_rad = atan(direction.x, direction.z) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
- code += " float angle2_rad = atan(direction.y, abs(direction.z)) + rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
- code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n";
- code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n";
- code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n";
- code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
- code += " vec_direction = normalize(vec_direction);\n";
- code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
+ code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
+ code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n";
+ code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n";
+ code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n";
+ code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n";
+ code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n";
+ code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
+ code += " vec_direction = normalize(vec_direction);\n";
+ code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
}
+ code += " }\n";
code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n";
code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle
@@ -338,36 +344,38 @@ void ParticlesMaterial::_update_shader() {
code += " CUSTOM.w = (1.0 - lifetime_randomness * rand_from_seed(alt_seed));\n";
code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random);\n"; // animation offset (0-1)
+ code += " if (RESTART_POSITION) {\n";
+
switch (emission_shape) {
case EMISSION_SHAPE_POINT: {
- //do none
+ //do none, identity (will later be multiplied by emission transform)
+ code += " TRANSFORM = mat4(vec4(1,0,0,0),vec4(0,1,0,0),vec4(0,0,1,0),vec4(0,0,0,1));\n";
} break;
case EMISSION_SHAPE_SPHERE: {
- code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n";
- code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n";
- code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n";
- code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n";
+ code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n";
+ code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n";
+ code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n";
+ code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n";
} break;
case EMISSION_SHAPE_BOX: {
- code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n";
+ code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n";
} break;
case EMISSION_SHAPE_POINTS:
case EMISSION_SHAPE_DIRECTED_POINTS: {
- code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n";
+ code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n";
if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) {
if (flags[FLAG_DISABLE_Z]) {
-
- code += " mat2 rotm;";
- code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n";
- code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n";
- code += " VELOCITY.xy = rotm * VELOCITY.xy;\n";
+ code += " mat2 rotm;";
+ code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n";
+ code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n";
+ code += " if (RESTART_VELOCITY) VELOCITY.xy = rotm * VELOCITY.xy;\n";
} else {
- code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n";
- code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n";
- code += " vec3 tangent = normalize(cross(v0, normal));\n";
- code += " vec3 bitangent = normalize(cross(tangent, normal));\n";
- code += " VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n";
+ code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n";
+ code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n";
+ code += " vec3 tangent = normalize(cross(v0, normal));\n";
+ code += " vec3 bitangent = normalize(cross(tangent, normal));\n";
+ code += " if (RESTART_VELOCITY) VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n";
}
}
} break;
@@ -375,68 +383,79 @@ void ParticlesMaterial::_update_shader() {
break;
}
}
- code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
- code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
+
+ code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
+ code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
if (flags[FLAG_DISABLE_Z]) {
- code += " VELOCITY.z = 0.0;\n";
- code += " TRANSFORM[3].z = 0.0;\n";
+ code += " VELOCITY.z = 0.0;\n";
+ code += " TRANSFORM[3].z = 0.0;\n";
}
+ code += " }\n";
code += " } else {\n";
code += " CUSTOM.y += DELTA / LIFETIME;\n";
- if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_linear_velocity = 0.0;\n";
+ }
if (flags[FLAG_DISABLE_Z]) {
-
- if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_orbit_velocity = 0.0;\n";
+ }
}
- if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_angular_velocity = 0.0;\n";
+ }
- if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid())
+ if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_linear_accel = 0.0;\n";
+ }
- if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid())
+ if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_radial_accel = 0.0;\n";
+ }
- if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid())
+ if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_tangent_accel = 0.0;\n";
+ }
- if (tex_parameters[PARAM_DAMPING].is_valid())
+ if (tex_parameters[PARAM_DAMPING].is_valid()) {
code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_damping = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANGLE].is_valid())
+ if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_angle = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANIM_SPEED].is_valid())
+ if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_anim_speed = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_anim_offset = 0.0;\n";
+ }
code += " vec3 force = gravity;\n";
code += " vec3 pos = TRANSFORM[3].xyz;\n";
@@ -461,7 +480,6 @@ void ParticlesMaterial::_update_shader() {
code += " VELOCITY += force * DELTA;\n";
code += " // orbit velocity\n";
if (flags[FLAG_DISABLE_Z]) {
-
code += " float orbit_amount = (orbit_velocity + tex_orbit_velocity) * mix(1.0, rand_from_seed(alt_seed), orbit_velocity_random);\n";
code += " if (orbit_amount != 0.0) {\n";
code += " float ang = orbit_amount * DELTA * pi * 2.0;\n";
@@ -491,15 +509,17 @@ void ParticlesMaterial::_update_shader() {
code += " }\n";
// apply color
// apply hue rotation
- if (tex_parameters[PARAM_SCALE].is_valid())
+ if (tex_parameters[PARAM_SCALE].is_valid()) {
code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_scale = 1.0;\n";
+ }
- if (tex_parameters[PARAM_HUE_VARIATION].is_valid())
+ if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_hue_variation = 0.0;\n";
+ }
code += " float hue_rot_angle = (hue_variation + tex_hue_variation) * pi * 2.0 * mix(1.0, hue_rot_rand * 2.0 - 1.0, hue_variation_random);\n";
code += " float hue_rot_c = cos(hue_rot_angle);\n";
@@ -524,15 +544,9 @@ void ParticlesMaterial::_update_shader() {
if (emission_color_texture.is_valid() && (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS)) {
code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n";
}
- if (trail_color_modifier.is_valid()) {
- code += " if (trail_divisor > 1) {\n";
- code += " COLOR *= textureLod(trail_color_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0);\n";
- code += " }\n";
- }
code += "\n";
if (flags[FLAG_DISABLE_Z]) {
-
if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
code += " if (length(VELOCITY) > 0.0) {\n";
code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n";
@@ -577,11 +591,6 @@ void ParticlesMaterial::_update_shader() {
code += " if (base_scale < 0.000001) {\n";
code += " base_scale = 0.000001;\n";
code += " }\n";
- if (trail_size_modifier.is_valid()) {
- code += " if (trail_divisor > 1) {\n";
- code += " base_scale *= textureLod(trail_size_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0).r;\n";
- code += " }\n";
- }
code += " TRANSFORM[0].xyz *= base_scale;\n";
code += " TRANSFORM[1].xyz *= base_scale;\n";
@@ -590,6 +599,33 @@ void ParticlesMaterial::_update_shader() {
code += " VELOCITY.z = 0.0;\n";
code += " TRANSFORM[3].z = 0.0;\n";
}
+ if (sub_emitter_mode != SUB_EMITTER_DISABLED) {
+ code += " int emit_count = 0;\n";
+ switch (sub_emitter_mode) {
+ case SUB_EMITTER_CONSTANT: {
+ code += " float interval_from = CUSTOM.y * LIFETIME - DELTA;\n";
+ code += " float interval_rem = sub_emitter_frequency - mod(interval_from,sub_emitter_frequency);\n";
+ code += " if (DELTA >= interval_rem) emit_count = 1;\n";
+ } break;
+ case SUB_EMITTER_AT_COLLISION: {
+ //not implemented yet
+ } break;
+ case SUB_EMITTER_AT_END: {
+ //not implemented yet
+ code += " float unit_delta = DELTA/LIFETIME;\n";
+ code += " float end_time = CUSTOM.w * 0.95;\n"; // if we do at the end we might miss it, as it can just get deactivated by emitter
+ code += " if (CUSTOM.y < end_time && (CUSTOM.y + unit_delta) >= end_time) emit_count = sub_emitter_amount_at_end;\n";
+ } break;
+ default: {
+ }
+ }
+ code += " for(int i=0;i<emit_count;i++) {\n";
+ code += " uint flags = FLAG_EMIT_POSITION|FLAG_EMIT_ROT_SCALE;\n";
+ code += " if (sub_emitter_keep_velocity) flags|=FLAG_EMIT_VELOCITY;\n";
+ code += " emit_particle(TRANSFORM,VELOCITY,vec4(0.0),vec4(0.0),flags);\n";
+ code += " }";
+ }
+
code += " if (CUSTOM.y > CUSTOM.w) {";
code += " ACTIVE = false;\n";
code += " }\n";
@@ -597,207 +633,181 @@ void ParticlesMaterial::_update_shader() {
code += "\n";
ShaderData shader_data;
- shader_data.shader = VS::get_singleton()->shader_create();
+ shader_data.shader = RS::get_singleton()->shader_create();
shader_data.users = 1;
- VS::get_singleton()->shader_set_code(shader_data.shader, code);
+ RS::get_singleton()->shader_set_code(shader_data.shader, code);
shader_map[mk] = shader_data;
- VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
+ RS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
}
void ParticlesMaterial::flush_changes() {
-
- if (material_mutex)
- material_mutex->lock();
+ MutexLock lock(material_mutex);
while (dirty_materials->first()) {
-
dirty_materials->first()->self()->_update_shader();
}
-
- if (material_mutex)
- material_mutex->unlock();
}
void ParticlesMaterial::_queue_shader_change() {
-
- if (material_mutex)
- material_mutex->lock();
+ MutexLock lock(material_mutex);
if (!element.in_list()) {
dirty_materials->add(&element);
}
-
- if (material_mutex)
- material_mutex->unlock();
}
bool ParticlesMaterial::_is_shader_dirty() const {
+ MutexLock lock(material_mutex);
- bool dirty = false;
-
- if (material_mutex)
- material_mutex->lock();
-
- dirty = element.in_list();
-
- if (material_mutex)
- material_mutex->unlock();
-
- return dirty;
+ return element.in_list();
}
void ParticlesMaterial::set_direction(Vector3 p_direction) {
-
direction = p_direction;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->direction, direction);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->direction, direction);
}
Vector3 ParticlesMaterial::get_direction() const {
-
return direction;
}
void ParticlesMaterial::set_spread(float p_spread) {
-
spread = p_spread;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->spread, p_spread);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->spread, p_spread);
}
float ParticlesMaterial::get_spread() const {
-
return spread;
}
void ParticlesMaterial::set_flatness(float p_flatness) {
-
flatness = p_flatness;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->flatness, p_flatness);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->flatness, p_flatness);
}
-float ParticlesMaterial::get_flatness() const {
+float ParticlesMaterial::get_flatness() const {
return flatness;
}
void ParticlesMaterial::set_param(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
parameters[p_param] = p_value;
switch (p_param) {
case PARAM_INITIAL_LINEAR_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity, p_value);
} break;
case PARAM_ANGULAR_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity, p_value);
} break;
case PARAM_ORBIT_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity, p_value);
} break;
case PARAM_LINEAR_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel, p_value);
} break;
case PARAM_RADIAL_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel, p_value);
} break;
case PARAM_TANGENTIAL_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel, p_value);
} break;
case PARAM_DAMPING: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping, p_value);
} break;
case PARAM_ANGLE: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle, p_value);
} break;
case PARAM_SCALE: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale, p_value);
} break;
case PARAM_HUE_VARIATION: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation, p_value);
} break;
case PARAM_ANIM_SPEED: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed, p_value);
} break;
case PARAM_ANIM_OFFSET: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset, p_value);
} break;
- case PARAM_MAX: break; // Can't happen, but silences warning
+ case PARAM_MAX:
+ break; // Can't happen, but silences warning
}
}
-float ParticlesMaterial::get_param(Parameter p_param) const {
+float ParticlesMaterial::get_param(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return parameters[p_param];
}
void ParticlesMaterial::set_param_randomness(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
randomness[p_param] = p_value;
switch (p_param) {
case PARAM_INITIAL_LINEAR_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity_random, p_value);
} break;
case PARAM_ANGULAR_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_random, p_value);
} break;
case PARAM_ORBIT_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_random, p_value);
} break;
case PARAM_LINEAR_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_random, p_value);
} break;
case PARAM_RADIAL_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_random, p_value);
} break;
case PARAM_TANGENTIAL_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_random, p_value);
} break;
case PARAM_DAMPING: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_random, p_value);
} break;
case PARAM_ANGLE: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle_random, p_value);
} break;
case PARAM_SCALE: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_random, p_value);
} break;
case PARAM_HUE_VARIATION: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_random, p_value);
} break;
case PARAM_ANIM_SPEED: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_random, p_value);
} break;
case PARAM_ANIM_OFFSET: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_random, p_value);
} break;
- case PARAM_MAX: break; // Can't happen, but silences warning
+ case PARAM_MAX:
+ break; // Can't happen, but silences warning
}
}
-float ParticlesMaterial::get_param_randomness(Parameter p_param) const {
+float ParticlesMaterial::get_param_randomness(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return randomness[p_param];
}
-static void _adjust_curve_range(const Ref<Texture> &p_texture, float p_min, float p_max) {
-
+static void _adjust_curve_range(const Ref<Texture2D> &p_texture, float p_min, float p_max) {
Ref<CurveTexture> curve_tex = p_texture;
- if (!curve_tex.is_valid())
+ if (!curve_tex.is_valid()) {
return;
+ }
curve_tex->ensure_default_setup(p_min, p_max);
}
-void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture> &p_texture) {
-
+void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
tex_parameters[p_param] = p_texture;
@@ -807,81 +817,78 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture>
//do none for this one
} break;
case PARAM_ANGULAR_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, p_texture);
_adjust_curve_range(p_texture, -360, 360);
} break;
case PARAM_ORBIT_VELOCITY: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, p_texture);
_adjust_curve_range(p_texture, -500, 500);
} break;
case PARAM_LINEAR_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, p_texture);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_RADIAL_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, p_texture);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_TANGENTIAL_ACCEL: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, p_texture);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_DAMPING: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, p_texture);
_adjust_curve_range(p_texture, 0, 100);
} break;
case PARAM_ANGLE: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, p_texture);
_adjust_curve_range(p_texture, -360, 360);
} break;
case PARAM_SCALE: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, p_texture);
_adjust_curve_range(p_texture, 0, 1);
} break;
case PARAM_HUE_VARIATION: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, p_texture);
_adjust_curve_range(p_texture, -1, 1);
} break;
case PARAM_ANIM_SPEED: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, p_texture);
_adjust_curve_range(p_texture, 0, 200);
} break;
case PARAM_ANIM_OFFSET: {
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, p_texture);
} break;
- case PARAM_MAX: break; // Can't happen, but silences warning
+ case PARAM_MAX:
+ break; // Can't happen, but silences warning
}
_queue_shader_change();
}
-Ref<Texture> ParticlesMaterial::get_param_texture(Parameter p_param) const {
- ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture>());
+Ref<Texture2D> ParticlesMaterial::get_param_texture(Parameter p_param) const {
+ ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture2D>());
return tex_parameters[p_param];
}
void ParticlesMaterial::set_color(const Color &p_color) {
-
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color, p_color);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color, p_color);
color = p_color;
}
Color ParticlesMaterial::get_color() const {
-
return color;
}
-void ParticlesMaterial::set_color_ramp(const Ref<Texture> &p_texture) {
-
+void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) {
color_ramp = p_texture;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
_queue_shader_change();
_change_notify();
}
-Ref<Texture> ParticlesMaterial::get_color_ramp() const {
-
+Ref<Texture2D> ParticlesMaterial::get_color_ramp() const {
return color_ramp;
}
@@ -907,149 +914,92 @@ void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) {
}
void ParticlesMaterial::set_emission_sphere_radius(float p_radius) {
-
emission_sphere_radius = p_radius;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_sphere_radius, p_radius);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_sphere_radius, p_radius);
}
void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) {
-
emission_box_extents = p_extents;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents);
}
-void ParticlesMaterial::set_emission_point_texture(const Ref<Texture> &p_points) {
-
+void ParticlesMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) {
emission_point_texture = p_points;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points);
}
-void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture> &p_normals) {
-
+void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) {
emission_normal_texture = p_normals;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals);
}
-void ParticlesMaterial::set_emission_color_texture(const Ref<Texture> &p_colors) {
-
+void ParticlesMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) {
emission_color_texture = p_colors;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors);
_queue_shader_change();
}
void ParticlesMaterial::set_emission_point_count(int p_count) {
-
emission_point_count = p_count;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_point_count, p_count);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_point_count, p_count);
}
ParticlesMaterial::EmissionShape ParticlesMaterial::get_emission_shape() const {
-
return emission_shape;
}
float ParticlesMaterial::get_emission_sphere_radius() const {
-
return emission_sphere_radius;
}
-Vector3 ParticlesMaterial::get_emission_box_extents() const {
+Vector3 ParticlesMaterial::get_emission_box_extents() const {
return emission_box_extents;
}
-Ref<Texture> ParticlesMaterial::get_emission_point_texture() const {
+Ref<Texture2D> ParticlesMaterial::get_emission_point_texture() const {
return emission_point_texture;
}
-Ref<Texture> ParticlesMaterial::get_emission_normal_texture() const {
+Ref<Texture2D> ParticlesMaterial::get_emission_normal_texture() const {
return emission_normal_texture;
}
-Ref<Texture> ParticlesMaterial::get_emission_color_texture() const {
-
+Ref<Texture2D> ParticlesMaterial::get_emission_color_texture() const {
return emission_color_texture;
}
int ParticlesMaterial::get_emission_point_count() const {
-
return emission_point_count;
}
-void ParticlesMaterial::set_trail_divisor(int p_divisor) {
-
- trail_divisor = p_divisor;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_divisor, p_divisor);
-}
-
-int ParticlesMaterial::get_trail_divisor() const {
-
- return trail_divisor;
-}
-
-void ParticlesMaterial::set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier) {
-
- trail_size_modifier = p_trail_size_modifier;
-
- Ref<CurveTexture> curve = trail_size_modifier;
- if (curve.is_valid()) {
- curve->ensure_default_setup();
- }
-
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_size_modifier, curve);
- _queue_shader_change();
-}
-
-Ref<CurveTexture> ParticlesMaterial::get_trail_size_modifier() const {
-
- return trail_size_modifier;
-}
-
-void ParticlesMaterial::set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier) {
-
- trail_color_modifier = p_trail_color_modifier;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_color_modifier, p_trail_color_modifier);
- _queue_shader_change();
-}
-
-Ref<GradientTexture> ParticlesMaterial::get_trail_color_modifier() const {
-
- return trail_color_modifier;
-}
-
void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) {
-
gravity = p_gravity;
Vector3 gset = gravity;
if (gset == Vector3()) {
gset = Vector3(0, -0.000001, 0); //as gravity is used as upvector in some calculations
}
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->gravity, gset);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->gravity, gset);
}
Vector3 ParticlesMaterial::get_gravity() const {
-
return gravity;
}
void ParticlesMaterial::set_lifetime_randomness(float p_lifetime) {
-
lifetime_randomness = p_lifetime;
- VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->lifetime_randomness, lifetime_randomness);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->lifetime_randomness, lifetime_randomness);
}
float ParticlesMaterial::get_lifetime_randomness() const {
-
return lifetime_randomness;
}
RID ParticlesMaterial::get_shader_rid() const {
-
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader;
}
void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
-
if (property.name == "color" && color_ramp.is_valid()) {
property.usage = 0;
}
@@ -1074,18 +1024,59 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
+ if (property.name == "sub_emitter_frequency" && sub_emitter_mode != SUB_EMITTER_CONSTANT) {
+ property.usage = 0;
+ }
+
+ if (property.name == "sub_emitter_amount_at_end" && sub_emitter_mode != SUB_EMITTER_AT_END) {
+ property.usage = 0;
+ }
+
if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) {
property.usage = 0;
}
}
-Shader::Mode ParticlesMaterial::get_shader_mode() const {
+void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) {
+ sub_emitter_mode = p_sub_emitter_mode;
+ _queue_shader_change();
+ _change_notify();
+}
+
+ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() const {
+ return sub_emitter_mode;
+}
+
+void ParticlesMaterial::set_sub_emitter_frequency(float p_frequency) {
+ sub_emitter_frequency = p_frequency;
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_frequency, 1.0 / p_frequency); //pas delta instead of frequency, since its easier to compute
+}
+float ParticlesMaterial::get_sub_emitter_frequency() const {
+ return sub_emitter_frequency;
+}
+void ParticlesMaterial::set_sub_emitter_amount_at_end(int p_amount) {
+ sub_emitter_amount_at_end = p_amount;
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_amount_at_end, p_amount);
+}
+
+int ParticlesMaterial::get_sub_emitter_amount_at_end() const {
+ return sub_emitter_amount_at_end;
+}
+
+void ParticlesMaterial::set_sub_emitter_keep_velocity(bool p_enable) {
+ sub_emitter_keep_velocity = p_enable;
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_keep_velocity, p_enable);
+}
+bool ParticlesMaterial::get_sub_emitter_keep_velocity() const {
+ return sub_emitter_keep_velocity;
+}
+
+Shader::Mode ParticlesMaterial::get_shader_mode() const {
return Shader::MODE_PARTICLES;
}
void ParticlesMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_direction", "degrees"), &ParticlesMaterial::set_direction);
ClassDB::bind_method(D_METHOD("get_direction"), &ParticlesMaterial::get_direction);
@@ -1134,34 +1125,34 @@ void ParticlesMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_emission_point_count", "point_count"), &ParticlesMaterial::set_emission_point_count);
ClassDB::bind_method(D_METHOD("get_emission_point_count"), &ParticlesMaterial::get_emission_point_count);
- ClassDB::bind_method(D_METHOD("set_trail_divisor", "divisor"), &ParticlesMaterial::set_trail_divisor);
- ClassDB::bind_method(D_METHOD("get_trail_divisor"), &ParticlesMaterial::get_trail_divisor);
-
- ClassDB::bind_method(D_METHOD("set_trail_size_modifier", "texture"), &ParticlesMaterial::set_trail_size_modifier);
- ClassDB::bind_method(D_METHOD("get_trail_size_modifier"), &ParticlesMaterial::get_trail_size_modifier);
-
- ClassDB::bind_method(D_METHOD("set_trail_color_modifier", "texture"), &ParticlesMaterial::set_trail_color_modifier);
- ClassDB::bind_method(D_METHOD("get_trail_color_modifier"), &ParticlesMaterial::get_trail_color_modifier);
-
ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity);
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity);
ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "randomness"), &ParticlesMaterial::set_lifetime_randomness);
ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &ParticlesMaterial::get_lifetime_randomness);
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_mode"), &ParticlesMaterial::get_sub_emitter_mode);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_mode", "mode"), &ParticlesMaterial::set_sub_emitter_mode);
+
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_frequency"), &ParticlesMaterial::get_sub_emitter_frequency);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_frequency", "hz"), &ParticlesMaterial::set_sub_emitter_frequency);
+
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_amount_at_end"), &ParticlesMaterial::get_sub_emitter_amount_at_end);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_amount_at_end", "amount"), &ParticlesMaterial::set_sub_emitter_amount_at_end);
+
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_keep_velocity"), &ParticlesMaterial::get_sub_emitter_keep_velocity);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_keep_velocity", "enable"), &ParticlesMaterial::set_sub_emitter_keep_velocity);
+
ADD_GROUP("Time", "");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness");
- ADD_GROUP("Trail", "trail_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_divisor", PROPERTY_HINT_RANGE, "1,1000000,1"), "set_trail_divisor", "get_trail_divisor");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_size_modifier", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_trail_size_modifier", "get_trail_size_modifier");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_color_modifier", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_trail_color_modifier", "get_trail_color_modifier");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness");
+
ADD_GROUP("Emission Shape", "emission_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_point_texture", "get_emission_point_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_normal_texture", "get_emission_normal_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_color_texture", "get_emission_color_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_point_texture", "get_emission_point_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_normal_texture", "get_emission_normal_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_color_texture", "get_emission_color_texture");
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_point_count", PROPERTY_HINT_RANGE, "0,1000000,1"), "set_emission_point_count", "get_emission_point_count");
ADD_GROUP("Flags", "flag_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY);
@@ -1169,61 +1160,67 @@ void ParticlesMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z);
ADD_GROUP("Direction", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness");
ADD_GROUP("Gravity", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity");
ADD_GROUP("Initial Velocity", "initial_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY);
ADD_GROUP("Angular Velocity", "angular_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY);
ADD_GROUP("Orbit Velocity", "orbit_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY);
ADD_GROUP("Linear Accel", "linear_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_LINEAR_ACCEL);
ADD_GROUP("Radial Accel", "radial_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_RADIAL_ACCEL);
ADD_GROUP("Tangential Accel", "tangential_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TANGENTIAL_ACCEL);
ADD_GROUP("Damping", "");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param", "get_param", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param", "get_param", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_DAMPING);
ADD_GROUP("Angle", "");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGLE);
ADD_GROUP("Scale", "");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_SCALE);
ADD_GROUP("Color", "");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp");
ADD_GROUP("Hue Variation", "hue_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION);
ADD_GROUP("Animation", "anim_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET);
+ ADD_GROUP("Sub Emitter", "sub_emitter_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,AtEnd,AtCollision"), "set_sub_emitter_mode", "get_sub_emitter_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sub_emitter_frequency", PROPERTY_HINT_RANGE, "0.01,100,0.01"), "set_sub_emitter_frequency", "get_sub_emitter_frequency");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_end", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_end", "get_sub_emitter_amount_at_end");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sub_emitter_keep_velocity"), "set_sub_emitter_keep_velocity", "get_sub_emitter_keep_velocity");
+
BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY);
BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY);
BIND_ENUM_CONSTANT(PARAM_ORBIT_VELOCITY);
@@ -1249,11 +1246,16 @@ void ParticlesMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);
+
+ BIND_ENUM_CONSTANT(SUB_EMITTER_DISABLED);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_CONSTANT);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_AT_END);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_AT_COLLISION);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_MAX);
}
ParticlesMaterial::ParticlesMaterial() :
element(this) {
-
set_direction(Vector3(1, 0, 0));
set_spread(45);
set_flatness(0);
@@ -1272,11 +1274,15 @@ ParticlesMaterial::ParticlesMaterial() :
set_emission_shape(EMISSION_SHAPE_POINT);
set_emission_sphere_radius(1);
set_emission_box_extents(Vector3(1, 1, 1));
- set_trail_divisor(1);
set_gravity(Vector3(0, -9.8, 0));
set_lifetime_randomness(0);
emission_point_count = 1;
+ set_sub_emitter_mode(SUB_EMITTER_DISABLED);
+ set_sub_emitter_frequency(4);
+ set_sub_emitter_amount_at_end(1);
+ set_sub_emitter_keep_velocity(false);
+
for (int i = 0; i < PARAM_MAX; i++) {
set_param_randomness(Parameter(i), 0);
}
@@ -1294,21 +1300,16 @@ ParticlesMaterial::ParticlesMaterial() :
}
ParticlesMaterial::~ParticlesMaterial() {
-
- if (material_mutex)
- material_mutex->lock();
+ MutexLock lock(material_mutex);
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
if (shader_map[current_key].users == 0) {
//deallocate shader, as it's no longer in use
- VS::get_singleton()->free(shader_map[current_key].shader);
+ RS::get_singleton()->free(shader_map[current_key].shader);
shader_map.erase(current_key);
}
- VS::get_singleton()->material_set_shader(_get_material(), RID());
+ RS::get_singleton()->material_set_shader(_get_material(), RID());
}
-
- if (material_mutex)
- material_mutex->unlock();
}
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index cc860b3812..fa8858f67f 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -34,13 +34,22 @@
#ifndef PARTICLES_MATERIAL_H
#define PARTICLES_MATERIAL_H
-class ParticlesMaterial : public Material {
+/*
+ TODO:
+-Path following
+*Manual emission
+-Sub Emitters
+-Attractors
+-Emitter positions deformable by bones
+-Collision
+-Proper trails
+*/
+class ParticlesMaterial : public Material {
GDCLASS(ParticlesMaterial, Material);
public:
enum Parameter {
-
PARAM_INITIAL_LINEAR_VELOCITY,
PARAM_ANGULAR_VELOCITY,
PARAM_ORBIT_VELOCITY,
@@ -72,18 +81,24 @@ public:
EMISSION_SHAPE_MAX
};
+ enum SubEmitterMode {
+ SUB_EMITTER_DISABLED,
+ SUB_EMITTER_CONSTANT,
+ SUB_EMITTER_AT_END,
+ SUB_EMITTER_AT_COLLISION,
+ SUB_EMITTER_MAX
+ };
+
private:
union MaterialKey {
-
struct {
uint32_t texture_mask : 16;
uint32_t texture_color : 1;
uint32_t flags : 4;
uint32_t emission_shape : 2;
- uint32_t trail_size_texture : 1;
- uint32_t trail_color_texture : 1;
uint32_t invalid_key : 1;
uint32_t has_emission_color : 1;
+ uint32_t sub_emitter : 2;
};
uint32_t key;
@@ -103,7 +118,6 @@ private:
MaterialKey current_key;
_FORCE_INLINE_ MaterialKey _compute_key() const {
-
MaterialKey mk;
mk.key = 0;
for (int i = 0; i < PARAM_MAX; i++) {
@@ -119,14 +133,13 @@ private:
mk.texture_color = color_ramp.is_valid() ? 1 : 0;
mk.emission_shape = emission_shape;
- mk.trail_color_texture = trail_color_modifier.is_valid() ? 1 : 0;
- mk.trail_size_texture = trail_size_modifier.is_valid() ? 1 : 0;
mk.has_emission_color = emission_shape >= EMISSION_SHAPE_POINTS && emission_color_texture.is_valid();
+ mk.sub_emitter = sub_emitter_mode;
return mk;
}
- static Mutex *material_mutex;
+ static Mutex material_mutex;
static SelfList<ParticlesMaterial>::List *dirty_materials;
struct ShaderNames {
@@ -181,13 +194,13 @@ private:
StringName emission_texture_normal;
StringName emission_texture_color;
- StringName trail_divisor;
- StringName trail_size_modifier;
- StringName trail_color_modifier;
-
StringName gravity;
StringName lifetime_randomness;
+
+ StringName sub_emitter_frequency;
+ StringName sub_emitter_amount_at_end;
+ StringName sub_emitter_keep_velocity;
};
static ShaderNames *shader_names;
@@ -205,36 +218,35 @@ private:
float parameters[PARAM_MAX];
float randomness[PARAM_MAX];
- Ref<Texture> tex_parameters[PARAM_MAX];
+ Ref<Texture2D> tex_parameters[PARAM_MAX];
Color color;
- Ref<Texture> color_ramp;
+ Ref<Texture2D> color_ramp;
bool flags[FLAG_MAX];
EmissionShape emission_shape;
float emission_sphere_radius;
Vector3 emission_box_extents;
- Ref<Texture> emission_point_texture;
- Ref<Texture> emission_normal_texture;
- Ref<Texture> emission_color_texture;
+ Ref<Texture2D> emission_point_texture;
+ Ref<Texture2D> emission_normal_texture;
+ Ref<Texture2D> emission_color_texture;
int emission_point_count;
bool anim_loop;
- int trail_divisor;
-
- Ref<CurveTexture> trail_size_modifier;
- Ref<GradientTexture> trail_color_modifier;
-
Vector3 gravity;
float lifetime_randomness;
+ SubEmitterMode sub_emitter_mode;
+ float sub_emitter_frequency;
+ int sub_emitter_amount_at_end;
+ bool sub_emitter_keep_velocity;
//do not save emission points here
protected:
static void _bind_methods();
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
public:
void set_direction(Vector3 p_direction);
@@ -252,14 +264,14 @@ public:
void set_param_randomness(Parameter p_param, float p_value);
float get_param_randomness(Parameter p_param) const;
- void set_param_texture(Parameter p_param, const Ref<Texture> &p_texture);
- Ref<Texture> get_param_texture(Parameter p_param) const;
+ void set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_param_texture(Parameter p_param) const;
void set_color(const Color &p_color);
Color get_color() const;
- void set_color_ramp(const Ref<Texture> &p_texture);
- Ref<Texture> get_color_ramp() const;
+ void set_color_ramp(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_color_ramp() const;
void set_flag(Flags p_flag, bool p_enable);
bool get_flag(Flags p_flag) const;
@@ -267,28 +279,19 @@ public:
void set_emission_shape(EmissionShape p_shape);
void set_emission_sphere_radius(float p_radius);
void set_emission_box_extents(Vector3 p_extents);
- void set_emission_point_texture(const Ref<Texture> &p_points);
- void set_emission_normal_texture(const Ref<Texture> &p_normals);
- void set_emission_color_texture(const Ref<Texture> &p_colors);
+ void set_emission_point_texture(const Ref<Texture2D> &p_points);
+ void set_emission_normal_texture(const Ref<Texture2D> &p_normals);
+ void set_emission_color_texture(const Ref<Texture2D> &p_colors);
void set_emission_point_count(int p_count);
EmissionShape get_emission_shape() const;
float get_emission_sphere_radius() const;
Vector3 get_emission_box_extents() const;
- Ref<Texture> get_emission_point_texture() const;
- Ref<Texture> get_emission_normal_texture() const;
- Ref<Texture> get_emission_color_texture() const;
+ Ref<Texture2D> get_emission_point_texture() const;
+ Ref<Texture2D> get_emission_normal_texture() const;
+ Ref<Texture2D> get_emission_color_texture() const;
int get_emission_point_count() const;
- void set_trail_divisor(int p_divisor);
- int get_trail_divisor() const;
-
- void set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier);
- Ref<CurveTexture> get_trail_size_modifier() const;
-
- void set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier);
- Ref<GradientTexture> get_trail_color_modifier() const;
-
void set_gravity(const Vector3 &p_gravity);
Vector3 get_gravity() const;
@@ -299,9 +302,21 @@ public:
static void finish_shaders();
static void flush_changes();
+ void set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode);
+ SubEmitterMode get_sub_emitter_mode() const;
+
+ void set_sub_emitter_frequency(float p_frequency);
+ float get_sub_emitter_frequency() const;
+
+ void set_sub_emitter_amount_at_end(int p_amount);
+ int get_sub_emitter_amount_at_end() const;
+
+ void set_sub_emitter_keep_velocity(bool p_enable);
+ bool get_sub_emitter_keep_velocity() const;
+
RID get_shader_rid() const;
- virtual Shader::Mode get_shader_mode() const;
+ virtual Shader::Mode get_shader_mode() const override;
ParticlesMaterial();
~ParticlesMaterial();
@@ -310,5 +325,6 @@ public:
VARIANT_ENUM_CAST(ParticlesMaterial::Parameter)
VARIANT_ENUM_CAST(ParticlesMaterial::Flags)
VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape)
+VARIANT_ENUM_CAST(ParticlesMaterial::SubEmitterMode)
#endif // PARTICLES_MATERIAL_H
diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp
index 0db115ecc0..59bf8c0e13 100644
--- a/scene/resources/physics_material.cpp
+++ b/scene/resources/physics_material.cpp
@@ -31,7 +31,6 @@
#include "physics_material.h"
void PhysicsMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_friction", "friction"), &PhysicsMaterial::set_friction);
ClassDB::bind_method(D_METHOD("get_friction"), &PhysicsMaterial::get_friction);
@@ -44,9 +43,9 @@ void PhysicsMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_absorbent", "absorbent"), &PhysicsMaterial::set_absorbent);
ClassDB::bind_method(D_METHOD("is_absorbent"), &PhysicsMaterial::is_absorbent);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction"), "set_friction", "get_friction");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rough"), "set_rough", "is_rough");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce"), "set_bounce", "get_bounce");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "absorbent"), "set_absorbent", "is_absorbent");
}
@@ -69,9 +68,3 @@ void PhysicsMaterial::set_absorbent(bool p_val) {
absorbent = p_val;
emit_changed();
}
-
-PhysicsMaterial::PhysicsMaterial() :
- friction(1),
- rough(false),
- bounce(0),
- absorbent(false) {}
diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h
index 2f7f4424b2..34aa7066df 100644
--- a/scene/resources/physics_material.h
+++ b/scene/resources/physics_material.h
@@ -28,22 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef physics_material_override_H
-#define physics_material_override_H
+#ifndef PHYSICS_MATERIAL_H
+#define PHYSICS_MATERIAL_H
#include "core/resource.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
class PhysicsMaterial : public Resource {
-
GDCLASS(PhysicsMaterial, Resource);
OBJ_SAVE_TYPE(PhysicsMaterial);
RES_BASE_EXTENSION("phymat");
- real_t friction;
- bool rough;
- real_t bounce;
- bool absorbent;
+ real_t friction = 1;
+ bool rough = false;
+ real_t bounce = 0;
+ bool absorbent = false;
protected:
static void _bind_methods();
@@ -69,7 +68,7 @@ public:
return absorbent ? -bounce : bounce;
}
- PhysicsMaterial();
+ PhysicsMaterial() {}
};
-#endif // physics_material_override_H
+#endif // PHYSICS_MATERIAL_H
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index 9a1d478777..df98d4cfd4 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -29,20 +29,18 @@
/*************************************************************************/
#include "polygon_path_finder.h"
-#include "core/math/geometry.h"
+#include "core/math/geometry_2d.h"
bool PolygonPathFinder::_is_point_inside(const Vector2 &p_point) const {
-
int crosses = 0;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 a = points[e.points[0]].pos;
Vector2 b = points[e.points[1]].pos;
- if (Geometry::segment_intersects_segment_2d(a, b, p_point, outside_point, NULL)) {
+ if (Geometry2D::segment_intersects_segment(a, b, p_point, outside_point, nullptr)) {
crosses++;
}
}
@@ -51,7 +49,6 @@ bool PolygonPathFinder::_is_point_inside(const Vector2 &p_point) const {
}
void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int> &p_connections) {
-
ERR_FAIL_COND(p_connections.size() & 1);
points.clear();
@@ -64,7 +61,6 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
bounds = Rect2();
for (int i = 0; i < p_points.size(); i++) {
-
points.write[i].pos = p_points[i];
points.write[i].penalty = 0;
@@ -84,7 +80,6 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
//insert edges (which are also connetions)
for (int i = 0; i < p_connections.size(); i += 2) {
-
Edge e(p_connections[i], p_connections[i + 1]);
ERR_FAIL_INDEX(e.points[0], point_count);
ERR_FAIL_INDEX(e.points[1], point_count);
@@ -96,30 +91,30 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
//fill the remaining connections based on visibility
for (int i = 0; i < point_count; i++) {
-
for (int j = i + 1; j < point_count; j++) {
-
- if (edges.has(Edge(i, j)))
+ if (edges.has(Edge(i, j))) {
continue; //if in edge ignore
+ }
Vector2 from = points[i].pos;
Vector2 to = points[j].pos;
- if (!_is_point_inside(from * 0.5 + to * 0.5)) //connection between points in inside space
+ if (!_is_point_inside(from * 0.5 + to * 0.5)) { //connection between points in inside space
continue;
+ }
bool valid = true;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
- if (e.points[0] == i || e.points[1] == i || e.points[0] == j || e.points[1] == j)
+ if (e.points[0] == i || e.points[1] == i || e.points[0] == j || e.points[1] == j) {
continue;
+ }
Vector2 a = points[e.points[0]].pos;
Vector2 b = points[e.points[1]].pos;
- if (Geometry::segment_intersects_segment_2d(a, b, from, to, NULL)) {
+ if (Geometry2D::segment_intersects_segment(a, b, from, to, nullptr)) {
valid = false;
break;
}
@@ -134,7 +129,6 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
}
Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector2 &p_to) {
-
Vector<Vector2> path;
Vector2 from = p_from;
@@ -143,19 +137,17 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
Edge ignore_to_edge(-1, -1);
if (!_is_point_inside(from)) {
-
float closest_dist = 1e20;
Vector2 closest_point;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 seg[2] = {
points[e.points[0]].pos,
points[e.points[1]].pos
};
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(from, seg);
+ Vector2 closest = Geometry2D::get_closest_point_to_segment(from, seg);
float d = from.distance_squared_to(closest);
if (d < closest_dist) {
@@ -173,14 +165,13 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
Vector2 closest_point;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 seg[2] = {
points[e.points[0]].pos,
points[e.points[1]].pos
};
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(to, seg);
+ Vector2 closest = Geometry2D::get_closest_point_to_segment(to, seg);
float d = to.distance_squared_to(closest);
if (d < closest_dist) {
@@ -195,28 +186,27 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//test direct connection
{
-
bool can_see_eachother = true;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
- if (e.points[0] == ignore_from_edge.points[0] && e.points[1] == ignore_from_edge.points[1])
+ if (e.points[0] == ignore_from_edge.points[0] && e.points[1] == ignore_from_edge.points[1]) {
continue;
- if (e.points[0] == ignore_to_edge.points[0] && e.points[1] == ignore_to_edge.points[1])
+ }
+ if (e.points[0] == ignore_to_edge.points[0] && e.points[1] == ignore_to_edge.points[1]) {
continue;
+ }
Vector2 a = points[e.points[0]].pos;
Vector2 b = points[e.points[1]].pos;
- if (Geometry::segment_intersects_segment_2d(a, b, from, to, NULL)) {
+ if (Geometry2D::segment_intersects_segment(a, b, from, to, nullptr)) {
can_see_eachother = false;
break;
}
}
if (can_see_eachother) {
-
path.push_back(from);
path.push_back(to);
return path;
@@ -237,7 +227,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
points.write[bidx].penalty = 0;
for (int i = 0; i < points.size() - 2; i++) {
-
bool valid_a = true;
bool valid_b = true;
points.write[i].prev = -1;
@@ -252,43 +241,40 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
- if (e.points[0] == i || e.points[1] == i)
+ if (e.points[0] == i || e.points[1] == i) {
continue;
+ }
Vector2 a = points[e.points[0]].pos;
Vector2 b = points[e.points[1]].pos;
if (valid_a) {
-
if (e.points[0] != ignore_from_edge.points[1] &&
e.points[1] != ignore_from_edge.points[1] &&
e.points[0] != ignore_from_edge.points[0] &&
e.points[1] != ignore_from_edge.points[0]) {
-
- if (Geometry::segment_intersects_segment_2d(a, b, from, points[i].pos, NULL)) {
+ if (Geometry2D::segment_intersects_segment(a, b, from, points[i].pos, nullptr)) {
valid_a = false;
}
}
}
if (valid_b) {
-
if (e.points[0] != ignore_to_edge.points[1] &&
e.points[1] != ignore_to_edge.points[1] &&
e.points[0] != ignore_to_edge.points[0] &&
e.points[1] != ignore_to_edge.points[0]) {
-
- if (Geometry::segment_intersects_segment_2d(a, b, to, points[i].pos, NULL)) {
+ if (Geometry2D::segment_intersects_segment(a, b, to, points[i].pos, nullptr)) {
valid_b = false;
}
}
}
- if (!valid_a && !valid_b)
+ if (!valid_a && !valid_b) {
break;
+ }
}
if (valid_a) {
@@ -308,7 +294,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
points.write[aidx].distance = 0;
points.write[aidx].prev = aidx;
for (Set<int>::Element *E = points[aidx].connections.front(); E; E = E->next()) {
-
open_list.insert(E->get());
points.write[E->get()].distance = from.distance_to(points[E->get()].pos);
points.write[E->get()].prev = aidx;
@@ -317,7 +302,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
bool found_route = false;
while (true) {
-
if (open_list.size() == 0) {
printf("open list empty\n");
break;
@@ -329,14 +313,12 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//this could be faster (cache previous results)
for (Set<int>::Element *E = open_list.front(); E; E = E->next()) {
-
const Point &p = points[E->get()];
float cost = p.distance;
cost += p.pos.distance_to(to);
cost += p.penalty;
if (cost < least_cost) {
-
least_cost_point = E->get();
least_cost = cost;
}
@@ -346,7 +328,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//open the neighbours for search
for (Set<int>::Element *E = np.connections.front(); E; E = E->next()) {
-
Point &p = points.write[E->get()];
float distance = np.pos.distance_to(p.pos) + np.distance;
@@ -354,7 +335,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//oh this was visited already, can we win the cost?
if (p.distance > distance) {
-
p.prev = least_cost_point; //reasign previous
p.distance = distance;
}
@@ -373,8 +353,9 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
}
- if (found_route)
+ if (found_route) {
break;
+ }
open_list.erase(least_cost_point);
}
@@ -391,7 +372,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
for (int i = 0; i < points.size() - 2; i++) {
-
points.write[i].connections.erase(aidx);
points.write[i].connections.erase(bidx);
points.write[i].prev = -1;
@@ -409,51 +389,48 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
void PolygonPathFinder::_set_data(const Dictionary &p_data) {
-
ERR_FAIL_COND(!p_data.has("points"));
ERR_FAIL_COND(!p_data.has("connections"));
ERR_FAIL_COND(!p_data.has("segments"));
ERR_FAIL_COND(!p_data.has("bounds"));
- PoolVector<Vector2> p = p_data["points"];
+ Vector<Vector2> p = p_data["points"];
Array c = p_data["connections"];
ERR_FAIL_COND(c.size() != p.size());
- if (c.size())
+ if (c.size()) {
return;
+ }
int pc = p.size();
points.resize(pc + 2);
- PoolVector<Vector2>::Read pr = p.read();
+ const Vector2 *pr = p.ptr();
for (int i = 0; i < pc; i++) {
points.write[i].pos = pr[i];
- PoolVector<int> con = c[i];
- PoolVector<int>::Read cr = con.read();
+ Vector<int> con = c[i];
+ const int *cr = con.ptr();
int cc = con.size();
for (int j = 0; j < cc; j++) {
-
points.write[i].connections.insert(cr[j]);
}
}
if (p_data.has("penalties")) {
-
- PoolVector<float> penalties = p_data["penalties"];
+ Vector<float> penalties = p_data["penalties"];
if (penalties.size() == pc) {
- PoolVector<float>::Read pr2 = penalties.read();
+ const float *pr2 = penalties.ptr();
for (int i = 0; i < pc; i++) {
points.write[i].penalty = pr2[i];
}
}
}
- PoolVector<int> segs = p_data["segments"];
+ Vector<int> segs = p_data["segments"];
int sc = segs.size();
ERR_FAIL_COND(sc & 1);
- PoolVector<int>::Read sr = segs.read();
+ const int *sr = segs.ptr();
for (int i = 0; i < sc; i += 2) {
-
Edge e(sr[i], sr[i + 1]);
edges.insert(e);
}
@@ -461,27 +438,26 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) {
}
Dictionary PolygonPathFinder::_get_data() const {
-
Dictionary d;
- PoolVector<Vector2> p;
- PoolVector<int> ind;
+ Vector<Vector2> p;
+ Vector<int> ind;
Array connections;
p.resize(MAX(0, points.size() - 2));
connections.resize(MAX(0, points.size() - 2));
ind.resize(edges.size() * 2);
- PoolVector<float> penalties;
+ Vector<float> penalties;
penalties.resize(MAX(0, points.size() - 2));
{
- PoolVector<Vector2>::Write wp = p.write();
- PoolVector<float>::Write pw = penalties.write();
+ Vector2 *wp = p.ptrw();
+ float *pw = penalties.ptrw();
for (int i = 0; i < points.size() - 2; i++) {
wp[i] = points[i].pos;
pw[i] = points[i].penalty;
- PoolVector<int> c;
+ Vector<int> c;
c.resize(points[i].connections.size());
{
- PoolVector<int>::Write cw = c.write();
+ int *cw = c.ptrw();
int idx = 0;
for (Set<int>::Element *E = points[i].connections.front(); E; E = E->next()) {
cw[idx++] = E->get();
@@ -491,8 +467,7 @@ Dictionary PolygonPathFinder::_get_data() const {
}
}
{
-
- PoolVector<int>::Write iw = ind.write();
+ int *iw = ind.ptrw();
int idx = 0;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
iw[idx++] = E->get().points[0];
@@ -510,24 +485,21 @@ Dictionary PolygonPathFinder::_get_data() const {
}
bool PolygonPathFinder::is_point_inside(const Vector2 &p_point) const {
-
return _is_point_inside(p_point);
}
Vector2 PolygonPathFinder::get_closest_point(const Vector2 &p_point) const {
-
float closest_dist = 1e20;
Vector2 closest_point;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 seg[2] = {
points[e.points[0]].pos,
points[e.points[1]].pos
};
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, seg);
+ Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, seg);
float d = p_point.distance_squared_to(closest);
if (d < closest_dist) {
@@ -542,7 +514,6 @@ Vector2 PolygonPathFinder::get_closest_point(const Vector2 &p_point) const {
}
Vector<Vector2> PolygonPathFinder::get_intersections(const Vector2 &p_from, const Vector2 &p_to) const {
-
Vector<Vector2> inters;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
@@ -550,7 +521,7 @@ Vector<Vector2> PolygonPathFinder::get_intersections(const Vector2 &p_from, cons
Vector2 b = points[E->get().points[1]].pos;
Vector2 res;
- if (Geometry::segment_intersects_segment_2d(a, b, p_from, p_to, &res)) {
+ if (Geometry2D::segment_intersects_segment(a, b, p_from, p_to, &res)) {
inters.push_back(res);
}
}
@@ -559,24 +530,20 @@ Vector<Vector2> PolygonPathFinder::get_intersections(const Vector2 &p_from, cons
}
Rect2 PolygonPathFinder::get_bounds() const {
-
return bounds;
}
void PolygonPathFinder::set_point_penalty(int p_point, float p_penalty) {
-
ERR_FAIL_INDEX(p_point, points.size() - 2);
points.write[p_point].penalty = p_penalty;
}
float PolygonPathFinder::get_point_penalty(int p_point) const {
-
ERR_FAIL_INDEX_V(p_point, points.size() - 2, 0);
return points[p_point].penalty;
}
void PolygonPathFinder::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("setup", "points", "connections"), &PolygonPathFinder::setup);
ClassDB::bind_method(D_METHOD("find_path", "from", "to"), &PolygonPathFinder::find_path);
ClassDB::bind_method(D_METHOD("get_intersections", "from", "to"), &PolygonPathFinder::get_intersections);
diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h
index 2ef5c89e2a..baee4dc20d 100644
--- a/scene/resources/polygon_path_finder.h
+++ b/scene/resources/polygon_path_finder.h
@@ -34,7 +34,6 @@
#include "core/resource.h"
class PolygonPathFinder : public Resource {
-
GDCLASS(PolygonPathFinder, Resource);
struct Point {
@@ -46,19 +45,17 @@ class PolygonPathFinder : public Resource {
};
struct Edge {
-
int points[2];
_FORCE_INLINE_ bool operator<(const Edge &p_edge) const {
-
- if (points[0] == p_edge.points[0])
+ if (points[0] == p_edge.points[0]) {
return points[1] < p_edge.points[1];
- else
+ } else {
return points[0] < p_edge.points[0];
+ }
}
Edge(int a = 0, int b = 0) {
-
if (a > b) {
SWAP(a, b);
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 74df72619a..8d9c5f07b2 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -29,42 +29,42 @@
/*************************************************************************/
#include "primitive_meshes.h"
-#include "servers/visual_server.h"
+#include "servers/rendering_server.h"
/**
PrimitiveMesh
*/
void PrimitiveMesh::_update() const {
-
Array arr;
- arr.resize(VS::ARRAY_MAX);
+ arr.resize(RS::ARRAY_MAX);
_create_mesh_array(arr);
- PoolVector<Vector3> points = arr[VS::ARRAY_VERTEX];
+ Vector<Vector3> points = arr[RS::ARRAY_VERTEX];
aabb = AABB();
int pc = points.size();
ERR_FAIL_COND(pc == 0);
{
-
- PoolVector<Vector3>::Read r = points.read();
+ const Vector3 *r = points.ptr();
for (int i = 0; i < pc; i++) {
- if (i == 0)
+ if (i == 0) {
aabb.position = r[i];
- else
+ } else {
aabb.expand_to(r[i]);
+ }
}
}
+ Vector<int> indices = arr[RS::ARRAY_INDEX];
+
if (flip_faces) {
- PoolVector<Vector3> normals = arr[VS::ARRAY_NORMAL];
- PoolVector<int> indices = arr[VS::ARRAY_INDEX];
- if (normals.size() && indices.size()) {
+ Vector<Vector3> normals = arr[RS::ARRAY_NORMAL];
+ if (normals.size() && indices.size()) {
{
int nc = normals.size();
- PoolVector<Vector3>::Write w = normals.write();
+ Vector3 *w = normals.ptrw();
for (int i = 0; i < nc; i++) {
w[i] = -w[i];
}
@@ -72,20 +72,22 @@ void PrimitiveMesh::_update() const {
{
int ic = indices.size();
- PoolVector<int>::Write w = indices.write();
+ int *w = indices.ptrw();
for (int i = 0; i < ic; i += 3) {
SWAP(w[i + 0], w[i + 1]);
}
}
- arr[VS::ARRAY_NORMAL] = normals;
- arr[VS::ARRAY_INDEX] = indices;
+ arr[RS::ARRAY_NORMAL] = normals;
+ arr[RS::ARRAY_INDEX] = indices;
}
}
+ array_len = pc;
+ index_array_len = indices.size();
// in with the new
- VisualServer::get_singleton()->mesh_clear(mesh);
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr);
- VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
+ RenderingServer::get_singleton()->mesh_clear(mesh);
+ RenderingServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (RenderingServer::PrimitiveType)primitive_type, arr);
+ RenderingServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
pending_request = false;
@@ -95,9 +97,9 @@ void PrimitiveMesh::_update() const {
}
void PrimitiveMesh::_request_update() {
-
- if (pending_request)
+ if (pending_request) {
return;
+ }
_update();
}
@@ -114,7 +116,7 @@ int PrimitiveMesh::surface_get_array_len(int p_idx) const {
_update();
}
- return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0);
+ return array_len;
}
int PrimitiveMesh::surface_get_array_index_len(int p_idx) const {
@@ -123,7 +125,7 @@ int PrimitiveMesh::surface_get_array_index_len(int p_idx) const {
_update();
}
- return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0);
+ return index_array_len;
}
Array PrimitiveMesh::surface_get_arrays(int p_surface) const {
@@ -132,25 +134,21 @@ Array PrimitiveMesh::surface_get_arrays(int p_surface) const {
_update();
}
- return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0);
+ return RenderingServer::get_singleton()->mesh_surface_get_arrays(mesh, 0);
}
-Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, 1, Array());
- if (pending_request) {
- _update();
- }
+Dictionary PrimitiveMesh::surface_get_lods(int p_surface) const {
+ return Dictionary(); //not really supported
+}
- return Array();
+Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const {
+ return Array(); //not really supported
}
uint32_t PrimitiveMesh::surface_get_format(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, 1, 0);
- if (pending_request) {
- _update();
- }
- return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0);
+ return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX | RS::ARRAY_COMPRESS_DEFAULT;
}
Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const {
@@ -164,7 +162,7 @@ void PrimitiveMesh::surface_set_material(int p_idx, const Ref<Material> &p_mater
}
Ref<Material> PrimitiveMesh::surface_get_material(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, 1, NULL);
+ ERR_FAIL_INDEX_V(p_idx, 1, nullptr);
return material;
}
@@ -206,7 +204,7 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &PrimitiveMesh::set_flip_faces);
ClassDB::bind_method(D_METHOD("get_flip_faces"), &PrimitiveMesh::get_flip_faces);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces");
}
@@ -215,7 +213,7 @@ void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
material = p_material;
if (!pending_request) {
// just apply it, else it'll happen when _update is called.
- VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
+ RenderingServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
_change_notify();
emit_changed();
};
@@ -230,14 +228,12 @@ Array PrimitiveMesh::get_mesh_arrays() const {
}
void PrimitiveMesh::set_custom_aabb(const AABB &p_custom) {
-
custom_aabb = p_custom;
- VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
+ RS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
emit_changed();
}
AABB PrimitiveMesh::get_custom_aabb() const {
-
return custom_aabb;
}
@@ -251,20 +247,22 @@ bool PrimitiveMesh::get_flip_faces() const {
}
PrimitiveMesh::PrimitiveMesh() {
-
flip_faces = false;
// defaults
- mesh = VisualServer::get_singleton()->mesh_create();
+ mesh = RenderingServer::get_singleton()->mesh_create();
// assume primitive triangles as the type, correct for all but one and it will change this :)
primitive_type = Mesh::PRIMITIVE_TRIANGLES;
// make sure we do an update after we've finished constructing our object
pending_request = true;
+
+ array_len = 0;
+ index_array_len = 0;
}
PrimitiveMesh::~PrimitiveMesh() {
- VisualServer::get_singleton()->free(mesh);
+ RenderingServer::get_singleton()->free(mesh);
}
/**
@@ -279,11 +277,11 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
// note, this has been aligned with our collision shape but I've left the descriptions as top/middle/bottom
- PoolVector<Vector3> points;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
- PoolVector<int> indices;
+ Vector<Vector3> points;
+ Vector<Vector3> normals;
+ Vector<float> tangents;
+ Vector<Vector2> uvs;
+ Vector<int> indices;
point = 0;
#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
@@ -300,19 +298,19 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
v /= (rings + 1);
w = sin(0.5 * Math_PI * v);
- z = radius * cos(0.5 * Math_PI * v);
+ y = radius * cos(0.5 * Math_PI * v);
for (i = 0; i <= radial_segments; i++) {
u = i;
u /= radial_segments;
- x = sin(u * (Math_PI * 2.0));
- y = -cos(u * (Math_PI * 2.0));
+ x = -sin(u * (Math_PI * 2.0));
+ z = cos(u * (Math_PI * 2.0));
- Vector3 p = Vector3(x * radius * w, y * radius * w, z);
- points.push_back(p + Vector3(0.0, 0.0, 0.5 * mid_height));
+ Vector3 p = Vector3(x * radius * w, y, -z * radius * w);
+ points.push_back(p + Vector3(0.0, 0.5 * mid_height, 0.0));
normals.push_back(p.normalized());
- ADD_TANGENT(-y, x, 0.0, 1.0)
+ ADD_TANGENT(z, 0.0, x, 1.0)
uvs.push_back(Vector2(u, v * onethird));
point++;
@@ -338,20 +336,20 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
v = j;
v /= (rings + 1);
- z = mid_height * v;
- z = (mid_height * 0.5) - z;
+ y = mid_height * v;
+ y = (mid_height * 0.5) - y;
for (i = 0; i <= radial_segments; i++) {
u = i;
u /= radial_segments;
- x = sin(u * (Math_PI * 2.0));
- y = -cos(u * (Math_PI * 2.0));
+ x = -sin(u * (Math_PI * 2.0));
+ z = cos(u * (Math_PI * 2.0));
- Vector3 p = Vector3(x * radius, y * radius, z);
+ Vector3 p = Vector3(x * radius, y, -z * radius);
points.push_back(p);
- normals.push_back(Vector3(x, y, 0.0));
- ADD_TANGENT(-y, x, 0.0, 1.0)
+ normals.push_back(Vector3(x, 0.0, -z));
+ ADD_TANGENT(z, 0.0, x, 1.0)
uvs.push_back(Vector2(u, onethird + (v * onethird)));
point++;
@@ -379,19 +377,19 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
v /= (rings + 1);
v += 1.0;
w = sin(0.5 * Math_PI * v);
- z = radius * cos(0.5 * Math_PI * v);
+ y = radius * cos(0.5 * Math_PI * v);
for (i = 0; i <= radial_segments; i++) {
float u2 = i;
u2 /= radial_segments;
- x = sin(u2 * (Math_PI * 2.0));
- y = -cos(u2 * (Math_PI * 2.0));
+ x = -sin(u2 * (Math_PI * 2.0));
+ z = cos(u2 * (Math_PI * 2.0));
- Vector3 p = Vector3(x * radius * w, y * radius * w, z);
- points.push_back(p + Vector3(0.0, 0.0, -0.5 * mid_height));
+ Vector3 p = Vector3(x * radius * w, y, -z * radius * w);
+ points.push_back(p + Vector3(0.0, -0.5 * mid_height, 0.0));
normals.push_back(p.normalized());
- ADD_TANGENT(-y, x, 0.0, 1.0)
+ ADD_TANGENT(z, 0.0, x, 1.0)
uvs.push_back(Vector2(u2, twothirds + ((v - 1.0) * onethird)));
point++;
@@ -410,11 +408,11 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
thisrow = point;
};
- p_arr[VS::ARRAY_VERTEX] = points;
- p_arr[VS::ARRAY_NORMAL] = normals;
- p_arr[VS::ARRAY_TANGENT] = tangents;
- p_arr[VS::ARRAY_TEX_UV] = uvs;
- p_arr[VS::ARRAY_INDEX] = indices;
+ p_arr[RS::ARRAY_VERTEX] = points;
+ p_arr[RS::ARRAY_NORMAL] = normals;
+ p_arr[RS::ARRAY_TANGENT] = tangents;
+ p_arr[RS::ARRAY_TEX_UV] = uvs;
+ p_arr[RS::ARRAY_INDEX] = indices;
}
void CapsuleMesh::_bind_methods() {
@@ -428,8 +426,8 @@ void CapsuleMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CapsuleMesh::set_rings);
ClassDB::bind_method(D_METHOD("get_rings"), &CapsuleMesh::get_rings);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "mid_height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_mid_height", "get_mid_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_mid_height", "get_mid_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_rings", "get_rings");
}
@@ -492,11 +490,11 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const {
// set our bounding box
- PoolVector<Vector3> points;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
- PoolVector<int> indices;
+ Vector<Vector3> points;
+ Vector<Vector3> normals;
+ Vector<float> tangents;
+ Vector<Vector2> uvs;
+ Vector<int> indices;
point = 0;
#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
@@ -667,11 +665,11 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const {
thisrow = point;
};
- p_arr[VS::ARRAY_VERTEX] = points;
- p_arr[VS::ARRAY_NORMAL] = normals;
- p_arr[VS::ARRAY_TANGENT] = tangents;
- p_arr[VS::ARRAY_TEX_UV] = uvs;
- p_arr[VS::ARRAY_INDEX] = indices;
+ p_arr[RS::ARRAY_VERTEX] = points;
+ p_arr[RS::ARRAY_NORMAL] = normals;
+ p_arr[RS::ARRAY_TANGENT] = tangents;
+ p_arr[RS::ARRAY_TEX_UV] = uvs;
+ p_arr[RS::ARRAY_INDEX] = indices;
}
void CubeMesh::_bind_methods() {
@@ -743,11 +741,11 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, y, z, u, v, radius;
- PoolVector<Vector3> points;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
- PoolVector<int> indices;
+ Vector<Vector3> points;
+ Vector<Vector3> normals;
+ Vector<float> tangents;
+ Vector<Vector2> uvs;
+ Vector<int> indices;
point = 0;
#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
@@ -868,11 +866,11 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
};
};
- p_arr[VS::ARRAY_VERTEX] = points;
- p_arr[VS::ARRAY_NORMAL] = normals;
- p_arr[VS::ARRAY_TANGENT] = tangents;
- p_arr[VS::ARRAY_TEX_UV] = uvs;
- p_arr[VS::ARRAY_INDEX] = indices;
+ p_arr[RS::ARRAY_VERTEX] = points;
+ p_arr[RS::ARRAY_NORMAL] = normals;
+ p_arr[RS::ARRAY_TANGENT] = tangents;
+ p_arr[RS::ARRAY_TEX_UV] = uvs;
+ p_arr[RS::ARRAY_INDEX] = indices;
}
void CylinderMesh::_bind_methods() {
@@ -888,9 +886,9 @@ void CylinderMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CylinderMesh::set_rings);
ClassDB::bind_method(D_METHOD("get_rings"), &CylinderMesh::get_rings);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "top_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_top_radius", "get_top_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bottom_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_bottom_radius", "get_bottom_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "top_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_top_radius", "get_top_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bottom_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_bottom_radius", "get_bottom_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_rings", "get_rings");
}
@@ -959,11 +957,11 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const {
Size2 start_pos = size * -0.5;
- PoolVector<Vector3> points;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
- PoolVector<int> indices;
+ Vector<Vector3> points;
+ Vector<Vector3> normals;
+ Vector<float> tangents;
+ Vector<Vector2> uvs;
+ Vector<int> indices;
point = 0;
#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
@@ -1007,11 +1005,11 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const {
thisrow = point;
};
- p_arr[VS::ARRAY_VERTEX] = points;
- p_arr[VS::ARRAY_NORMAL] = normals;
- p_arr[VS::ARRAY_TANGENT] = tangents;
- p_arr[VS::ARRAY_TEX_UV] = uvs;
- p_arr[VS::ARRAY_INDEX] = indices;
+ p_arr[RS::ARRAY_VERTEX] = points;
+ p_arr[RS::ARRAY_NORMAL] = normals;
+ p_arr[RS::ARRAY_TANGENT] = tangents;
+ p_arr[RS::ARRAY_TEX_UV] = uvs;
+ p_arr[RS::ARRAY_INDEX] = indices;
}
void PlaneMesh::_bind_methods() {
@@ -1076,11 +1074,11 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const {
// set our bounding box
- PoolVector<Vector3> points;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
- PoolVector<int> indices;
+ Vector<Vector3> points;
+ Vector<Vector3> normals;
+ Vector<float> tangents;
+ Vector<Vector2> uvs;
+ Vector<int> indices;
point = 0;
#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
@@ -1267,11 +1265,11 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const {
thisrow = point;
};
- p_arr[VS::ARRAY_VERTEX] = points;
- p_arr[VS::ARRAY_NORMAL] = normals;
- p_arr[VS::ARRAY_TANGENT] = tangents;
- p_arr[VS::ARRAY_TEX_UV] = uvs;
- p_arr[VS::ARRAY_INDEX] = indices;
+ p_arr[RS::ARRAY_VERTEX] = points;
+ p_arr[RS::ARRAY_NORMAL] = normals;
+ p_arr[RS::ARRAY_TANGENT] = tangents;
+ p_arr[RS::ARRAY_TEX_UV] = uvs;
+ p_arr[RS::ARRAY_INDEX] = indices;
}
void PrismMesh::_bind_methods() {
@@ -1288,7 +1286,7 @@ void PrismMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_subdivide_depth", "segments"), &PrismMesh::set_subdivide_depth);
ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PrismMesh::get_subdivide_depth);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_height", "get_subdivide_height");
@@ -1354,10 +1352,10 @@ PrismMesh::PrismMesh() {
*/
void QuadMesh::_create_mesh_array(Array &p_arr) const {
- PoolVector<Vector3> faces;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
+ Vector<Vector3> faces;
+ Vector<Vector3> normals;
+ Vector<float> tangents;
+ Vector<Vector2> uvs;
faces.resize(6);
normals.resize(6);
@@ -1379,7 +1377,6 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
};
for (int i = 0; i < 6; i++) {
-
int j = indices[i];
faces.set(i, quad_faces[j]);
normals.set(i, Vector3(0, 0, 1));
@@ -1398,10 +1395,10 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
uvs.set(i, quad_uv[j]);
}
- p_arr[VS::ARRAY_VERTEX] = faces;
- p_arr[VS::ARRAY_NORMAL] = normals;
- p_arr[VS::ARRAY_TANGENT] = tangents;
- p_arr[VS::ARRAY_TEX_UV] = uvs;
+ p_arr[RS::ARRAY_VERTEX] = faces;
+ p_arr[RS::ARRAY_NORMAL] = normals;
+ p_arr[RS::ARRAY_TANGENT] = tangents;
+ p_arr[RS::ARRAY_TEX_UV] = uvs;
}
void QuadMesh::_bind_methods() {
@@ -1434,11 +1431,11 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
// set our bounding box
- PoolVector<Vector3> points;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
- PoolVector<int> indices;
+ Vector<Vector3> points;
+ Vector<Vector3> normals;
+ Vector<float> tangents;
+ Vector<Vector2> uvs;
+ Vector<int> indices;
point = 0;
#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
@@ -1491,11 +1488,11 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
thisrow = point;
};
- p_arr[VS::ARRAY_VERTEX] = points;
- p_arr[VS::ARRAY_NORMAL] = normals;
- p_arr[VS::ARRAY_TANGENT] = tangents;
- p_arr[VS::ARRAY_TEX_UV] = uvs;
- p_arr[VS::ARRAY_INDEX] = indices;
+ p_arr[RS::ARRAY_VERTEX] = points;
+ p_arr[RS::ARRAY_NORMAL] = normals;
+ p_arr[RS::ARRAY_TANGENT] = tangents;
+ p_arr[RS::ARRAY_TEX_UV] = uvs;
+ p_arr[RS::ARRAY_INDEX] = indices;
}
void SphereMesh::_bind_methods() {
@@ -1512,8 +1509,8 @@ void SphereMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_is_hemisphere", "is_hemisphere"), &SphereMesh::set_is_hemisphere);
ClassDB::bind_method(D_METHOD("get_is_hemisphere"), &SphereMesh::get_is_hemisphere);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_rings", "get_rings");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_hemisphere"), "set_is_hemisphere", "get_is_hemisphere");
@@ -1578,11 +1575,11 @@ SphereMesh::SphereMesh() {
*/
void PointMesh::_create_mesh_array(Array &p_arr) const {
- PoolVector<Vector3> faces;
+ Vector<Vector3> faces;
faces.resize(1);
faces.set(0, Vector3(0.0, 0.0, 0.0));
- p_arr[VS::ARRAY_VERTEX] = faces;
+ p_arr[RS::ARRAY_VERTEX] = faces;
}
PointMesh::PointMesh() {
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 47126f1862..f0ae611b5e 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -42,7 +42,6 @@
This class is set apart that it assumes a single surface is always generated for our mesh.
*/
class PrimitiveMesh : public Mesh {
-
GDCLASS(PrimitiveMesh, Mesh);
private:
@@ -50,6 +49,9 @@ private:
mutable AABB aabb;
AABB custom_aabb;
+ mutable int array_len;
+ mutable int index_array_len;
+
Ref<Material> material;
bool flip_faces;
@@ -65,19 +67,20 @@ protected:
void _request_update();
public:
- virtual int get_surface_count() const;
- virtual int surface_get_array_len(int p_idx) const;
- virtual int surface_get_array_index_len(int p_idx) const;
- virtual Array surface_get_arrays(int p_surface) const;
- virtual Array surface_get_blend_shape_arrays(int p_surface) const;
- virtual uint32_t surface_get_format(int p_idx) const;
- virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const;
- virtual void surface_set_material(int p_idx, const Ref<Material> &p_material);
- virtual Ref<Material> surface_get_material(int p_idx) const;
- virtual int get_blend_shape_count() const;
- virtual StringName get_blend_shape_name(int p_index) const;
- virtual AABB get_aabb() const;
- virtual RID get_rid() const;
+ virtual int get_surface_count() const override;
+ virtual int surface_get_array_len(int p_idx) const override;
+ virtual int surface_get_array_index_len(int p_idx) const override;
+ virtual Array surface_get_arrays(int p_surface) const override;
+ virtual Array surface_get_blend_shape_arrays(int p_surface) const override;
+ virtual Dictionary surface_get_lods(int p_surface) const override;
+ virtual uint32_t surface_get_format(int p_idx) const override;
+ virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const override;
+ virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) override;
+ virtual Ref<Material> surface_get_material(int p_idx) const override;
+ virtual int get_blend_shape_count() const override;
+ virtual StringName get_blend_shape_name(int p_index) const override;
+ virtual AABB get_aabb() const override;
+ virtual RID get_rid() const override;
void set_material(const Ref<Material> &p_material);
Ref<Material> get_material() const;
@@ -108,7 +111,7 @@ private:
protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
void set_radius(const float p_radius);
@@ -130,7 +133,6 @@ public:
Similar to test cube but with subdivision support and different texture coordinates
*/
class CubeMesh : public PrimitiveMesh {
-
GDCLASS(CubeMesh, PrimitiveMesh);
private:
@@ -141,7 +143,7 @@ private:
protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
void set_size(const Vector3 &p_size);
@@ -164,7 +166,6 @@ public:
*/
class CylinderMesh : public PrimitiveMesh {
-
GDCLASS(CylinderMesh, PrimitiveMesh);
private:
@@ -176,7 +177,7 @@ private:
protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
void set_top_radius(const float p_radius);
@@ -201,7 +202,6 @@ public:
Similar to quadmesh but with tessellation support
*/
class PlaneMesh : public PrimitiveMesh {
-
GDCLASS(PlaneMesh, PrimitiveMesh);
private:
@@ -211,7 +211,7 @@ private:
protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
void set_size(const Size2 &p_size);
@@ -230,7 +230,6 @@ public:
A prism shapen, handy for ramps, triangles, etc.
*/
class PrismMesh : public PrimitiveMesh {
-
GDCLASS(PrismMesh, PrimitiveMesh);
private:
@@ -242,7 +241,7 @@ private:
protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
void set_left_to_right(const float p_left_to_right);
@@ -268,7 +267,6 @@ public:
*/
class QuadMesh : public PrimitiveMesh {
-
GDCLASS(QuadMesh, PrimitiveMesh);
private:
@@ -276,7 +274,7 @@ private:
protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
QuadMesh();
@@ -289,7 +287,6 @@ public:
A sphere..
*/
class SphereMesh : public PrimitiveMesh {
-
GDCLASS(SphereMesh, PrimitiveMesh);
private:
@@ -301,7 +298,7 @@ private:
protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
void set_radius(const float p_radius);
@@ -327,11 +324,10 @@ public:
*/
class PointMesh : public PrimitiveMesh {
-
GDCLASS(PointMesh, PrimitiveMesh)
protected:
- virtual void _create_mesh_array(Array &p_arr) const;
+ virtual void _create_mesh_array(Array &p_arr) const override;
public:
PointMesh();
diff --git a/scene/resources/ray_shape_2d.cpp b/scene/resources/ray_shape_2d.cpp
new file mode 100644
index 0000000000..67c4f84749
--- /dev/null
+++ b/scene/resources/ray_shape_2d.cpp
@@ -0,0 +1,105 @@
+/*************************************************************************/
+/* ray_shape_2d.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "ray_shape_2d.h"
+
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
+
+void RayShape2D::_update_shape() {
+ Dictionary d;
+ d["length"] = length;
+ d["slips_on_slope"] = slips_on_slope;
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), d);
+ emit_changed();
+}
+
+void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
+ Vector2 tip = Vector2(0, get_length());
+ RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3);
+ Vector<Vector2> pts;
+ float tsize = 4;
+ pts.push_back(tip + Vector2(0, tsize));
+ pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0));
+ pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0));
+ Vector<Color> cols;
+ for (int i = 0; i < 3; i++) {
+ cols.push_back(p_color);
+ }
+ RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
+}
+
+Rect2 RayShape2D::get_rect() const {
+ Rect2 rect;
+ rect.position = Vector2();
+ rect.expand_to(Vector2(0, length));
+ rect = rect.grow(Math_SQRT12 * 4);
+ return rect;
+}
+
+real_t RayShape2D::get_enclosing_radius() const {
+ return length;
+}
+
+void RayShape2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length);
+ ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length);
+
+ ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope);
+ ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope");
+}
+
+void RayShape2D::set_length(real_t p_length) {
+ length = p_length;
+ _update_shape();
+}
+
+real_t RayShape2D::get_length() const {
+ return length;
+}
+
+void RayShape2D::set_slips_on_slope(bool p_active) {
+ slips_on_slope = p_active;
+ _update_shape();
+}
+
+bool RayShape2D::get_slips_on_slope() const {
+ return slips_on_slope;
+}
+
+RayShape2D::RayShape2D() :
+ Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) {
+ length = 20;
+ slips_on_slope = false;
+ _update_shape();
+}
diff --git a/scene/resources/ray_shape_2d.h b/scene/resources/ray_shape_2d.h
new file mode 100644
index 0000000000..c8202ca16c
--- /dev/null
+++ b/scene/resources/ray_shape_2d.h
@@ -0,0 +1,61 @@
+/*************************************************************************/
+/* ray_shape_2d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RAY_SHAPE_2D_H
+#define RAY_SHAPE_2D_H
+
+#include "scene/resources/shape_2d.h"
+
+class RayShape2D : public Shape2D {
+ GDCLASS(RayShape2D, Shape2D);
+
+ real_t length;
+ bool slips_on_slope;
+
+ void _update_shape();
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_length(real_t p_length);
+ real_t get_length() const;
+
+ void set_slips_on_slope(bool p_active);
+ bool get_slips_on_slope() const;
+
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
+
+ RayShape2D();
+};
+
+#endif // RAY_SHAPE_2D_H
diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape_3d.cpp
index 3062e96293..39df4c22f9 100644
--- a/scene/resources/ray_shape.cpp
+++ b/scene/resources/ray_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* ray_shape.cpp */
+/* ray_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,12 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "ray_shape.h"
+#include "ray_shape_3d.h"
-#include "servers/physics_server.h"
-
-Vector<Vector3> RayShape::get_debug_mesh_lines() {
+#include "servers/physics_server_3d.h"
+Vector<Vector3> RayShape3D::get_debug_mesh_lines() const {
Vector<Vector3> points;
points.push_back(Vector3());
points.push_back(Vector3(0, 0, get_length()));
@@ -41,55 +40,53 @@ Vector<Vector3> RayShape::get_debug_mesh_lines() {
return points;
}
-void RayShape::_update_shape() {
+real_t RayShape3D::get_enclosing_radius() const {
+ return length;
+}
+void RayShape3D::_update_shape() {
Dictionary d;
d["length"] = length;
d["slips_on_slope"] = slips_on_slope;
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), d);
- Shape::_update_shape();
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);
+ Shape3D::_update_shape();
}
-void RayShape::set_length(float p_length) {
-
+void RayShape3D::set_length(float p_length) {
length = p_length;
_update_shape();
notify_change_to_owners();
_change_notify("length");
}
-float RayShape::get_length() const {
-
+float RayShape3D::get_length() const {
return length;
}
-void RayShape::set_slips_on_slope(bool p_active) {
-
+void RayShape3D::set_slips_on_slope(bool p_active) {
slips_on_slope = p_active;
_update_shape();
notify_change_to_owners();
_change_notify("slips_on_slope");
}
-bool RayShape::get_slips_on_slope() const {
+bool RayShape3D::get_slips_on_slope() const {
return slips_on_slope;
}
-void RayShape::_bind_methods() {
+void RayShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape3D::set_length);
+ ClassDB::bind_method(D_METHOD("get_length"), &RayShape3D::get_length);
- ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape::set_length);
- ClassDB::bind_method(D_METHOD("get_length"), &RayShape::get_length);
+ ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape3D::set_slips_on_slope);
+ ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape3D::get_slips_on_slope);
- ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape::set_slips_on_slope);
- ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape::get_slips_on_slope);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope");
}
-RayShape::RayShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
-
+RayShape3D::RayShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_RAY)) {
length = 1.0;
slips_on_slope = false;
diff --git a/scene/resources/ray_shape.h b/scene/resources/ray_shape_3d.h
index ddf9f56ea3..a1a6702564 100644
--- a/scene/resources/ray_shape.h
+++ b/scene/resources/ray_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* ray_shape.h */
+/* ray_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,17 +30,16 @@
#ifndef RAY_SHAPE_H
#define RAY_SHAPE_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class RayShape : public Shape {
-
- GDCLASS(RayShape, Shape);
+class RayShape3D : public Shape3D {
+ GDCLASS(RayShape3D, Shape3D);
float length;
bool slips_on_slope;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
void set_length(float p_length);
@@ -49,8 +48,9 @@ public:
void set_slips_on_slope(bool p_active);
bool get_slips_on_slope() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- RayShape();
+ RayShape3D();
};
#endif // RAY_SHAPE_H
diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp
index 0030e6dd4f..949fddf2e7 100644
--- a/scene/resources/rectangle_shape_2d.cpp
+++ b/scene/resources/rectangle_shape_2d.cpp
@@ -30,37 +30,35 @@
#include "rectangle_shape_2d.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
void RectangleShape2D::_update_shape() {
-
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), extents);
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), extents);
emit_changed();
}
void RectangleShape2D::set_extents(const Vector2 &p_extents) {
-
extents = p_extents;
_update_shape();
}
Vector2 RectangleShape2D::get_extents() const {
-
return extents;
}
void RectangleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
- VisualServer::get_singleton()->canvas_item_add_rect(p_to_rid, Rect2(-extents, extents * 2.0), p_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(p_to_rid, Rect2(-extents, extents * 2.0), p_color);
}
Rect2 RectangleShape2D::get_rect() const {
-
return Rect2(-extents, extents * 2.0);
}
-void RectangleShape2D::_bind_methods() {
+real_t RectangleShape2D::get_enclosing_radius() const {
+ return extents.length();
+}
+void RectangleShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &RectangleShape2D::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &RectangleShape2D::get_extents);
@@ -68,8 +66,7 @@ void RectangleShape2D::_bind_methods() {
}
RectangleShape2D::RectangleShape2D() :
- Shape2D(Physics2DServer::get_singleton()->rectangle_shape_create()) {
-
+ Shape2D(PhysicsServer2D::get_singleton()->rectangle_shape_create()) {
extents = Vector2(10, 10);
_update_shape();
}
diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h
index 686b421a2a..6efa7ab9c8 100644
--- a/scene/resources/rectangle_shape_2d.h
+++ b/scene/resources/rectangle_shape_2d.h
@@ -46,8 +46,9 @@ public:
void set_extents(const Vector2 &p_extents);
Vector2 get_extents() const;
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
RectangleShape2D();
};
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index eb05defddd..d4d8018d43 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -35,7 +35,7 @@
#include "core/project_settings.h"
#include "core/version.h"
-//version 2: changed names for basis, aabb, poolvectors, etc.
+//version 2: changed names for basis, aabb, Vectors, etc.
#define FORMAT_VERSION 2
#include "core/os/dir_access.h"
@@ -45,18 +45,15 @@
///
-void ResourceInteractiveLoaderText::set_local_path(const String &p_local_path) {
-
+void ResourceLoaderText::set_local_path(const String &p_local_path) {
res_path = p_local_path;
}
-Ref<Resource> ResourceInteractiveLoaderText::get_resource() {
-
+Ref<Resource> ResourceLoaderText::get_resource() {
return resource;
}
-Error ResourceInteractiveLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
+Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -85,8 +82,7 @@ Error ResourceInteractiveLoaderText::_parse_sub_resource_dummy(DummyReadData *p_
return OK;
}
-Error ResourceInteractiveLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
+Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -109,8 +105,7 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource_dummy(DummyReadData *p_
return OK;
}
-Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
+Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -120,18 +115,21 @@ Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream *
int index = token.value;
- String path = local_path + "::" + itos(index);
+ if (use_nocache) {
+ r_res = int_resources[index];
+ } else {
+ String path = local_path + "::" + itos(index);
- if (!ignore_resource_parsing) {
+ if (!ignore_resource_parsing) {
+ if (!ResourceCache::has(path)) {
+ r_err_str = "Can't load cached sub-resource: " + path;
+ return ERR_PARSE_ERROR;
+ }
- if (!ResourceCache::has(path)) {
- r_err_str = "Can't load cached sub-resource: " + path;
- return ERR_PARSE_ERROR;
+ r_res = RES(ResourceCache::get(path));
+ } else {
+ r_res = RES();
}
-
- r_res = RES(ResourceCache::get(path));
- } else {
- r_res = RES();
}
VariantParser::get_token(p_stream, token, line, r_err_str);
@@ -143,8 +141,7 @@ Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream *
return OK;
}
-Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
+Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -155,7 +152,6 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream *
int id = token.value;
if (!ignore_resource_parsing) {
-
if (!ext_resources.has(id)) {
r_err_str = "Can't load cached ext-resource #" + itos(id);
return ERR_PARSE_ERROR;
@@ -164,15 +160,28 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream *
String path = ext_resources[id].path;
String type = ext_resources[id].type;
- if (path.find("://") == -1 && path.is_rel_path()) {
- // path is relative to file being loaded, so convert to a resource path
- path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
- }
-
- r_res = ResourceLoader::load(path, type);
-
- if (r_res.is_null()) {
- WARN_PRINT(String("Couldn't load external resource: " + path).utf8().get_data());
+ if (ext_resources[id].cache.is_valid()) {
+ r_res = ext_resources[id].cache;
+ } else if (use_sub_threads) {
+ RES res = ResourceLoader::load_threaded_get(path);
+ if (res.is_null()) {
+ if (ResourceLoader::get_abort_on_missing_resources()) {
+ error = ERR_FILE_CORRUPT;
+ error_text = "[ext_resource] referenced nonexistent resource at: " + path;
+ _printerr();
+ return error;
+ } else {
+ ResourceLoader::notify_dependency_error(local_path, path, type);
+ }
+ } else {
+ ext_resources[id].cache = res;
+ r_res = res;
+ }
+ } else {
+ error = ERR_FILE_CORRUPT;
+ error_text = "[ext_resource] referenced non-loaded resource at: " + path;
+ _printerr();
+ return error;
}
} else {
r_res = RES();
@@ -187,14 +196,12 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream *
return OK;
}
-Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::ResourceParser &parser) {
+Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourceParser &parser) {
Ref<PackedScene> packed_scene;
packed_scene.instance();
while (true) {
-
if (next_tag.name == "node") {
-
int parent = -1;
int owner = -1;
int type = -1;
@@ -220,7 +227,6 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
}
if (next_tag.fields.has("instance")) {
-
instance = packed_scene->get_state()->add_value(next_tag.fields["instance"]);
if (packed_scene->get_state()->get_node_count() == 0 && parent == -1) {
@@ -230,7 +236,6 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
}
if (next_tag.fields.has("instance_placeholder")) {
-
String path = next_tag.fields["instance_placeholder"];
int path_v = packed_scene->get_state()->add_value(path);
@@ -248,8 +253,9 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
if (next_tag.fields.has("owner")) {
owner = packed_scene->get_state()->add_node_path(next_tag.fields["owner"]);
} else {
- if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1))
+ if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1)) {
owner = 0; //if no owner, owner is root
+ }
}
if (next_tag.fields.has("index")) {
@@ -259,7 +265,6 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
int node_id = packed_scene->get_state()->add_node(parent, owner, type, name, instance, index);
if (next_tag.fields.has("groups")) {
-
Array groups = next_tag.fields["groups"];
for (int i = 0; i < groups.size(); i++) {
packed_scene->get_state()->add_node_group(node_id, packed_scene->get_state()->add_name(groups[i]));
@@ -267,7 +272,6 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
}
while (true) {
-
String assign;
Variant value;
@@ -278,6 +282,7 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
_printerr();
return Ref<PackedScene>();
} else {
+ error = OK;
return packed_scene;
}
}
@@ -292,7 +297,6 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
}
}
} else if (next_tag.name == "connection") {
-
if (!next_tag.fields.has("from")) {
error = ERR_FILE_CORRUPT;
error_text = "missing 'from' field from connection tag";
@@ -321,7 +325,7 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
NodePath to = next_tag.fields["to"];
StringName method = next_tag.fields["method"];
StringName signal = next_tag.fields["signal"];
- int flags = CONNECT_PERSIST;
+ int flags = Object::CONNECT_PERSIST;
Array binds;
if (next_tag.fields.has("flags")) {
@@ -352,11 +356,11 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
_printerr();
return Ref<PackedScene>();
} else {
+ error = OK;
return packed_scene;
}
}
} else if (next_tag.name == "editable") {
-
if (!next_tag.fields.has("path")) {
error = ERR_FILE_CORRUPT;
error_text = "missing 'path' field from connection tag";
@@ -375,26 +379,27 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R
_printerr();
return Ref<PackedScene>();
} else {
+ error = OK;
return packed_scene;
}
}
} else {
-
error = ERR_FILE_CORRUPT;
_printerr();
return Ref<PackedScene>();
}
}
-
- return packed_scene;
}
-Error ResourceInteractiveLoaderText::poll() {
-
- if (error != OK)
+Error ResourceLoaderText::load() {
+ if (error != OK) {
return error;
+ }
- if (next_tag.name == "ext_resource") {
+ while (true) {
+ if (next_tag.name != "ext_resource") {
+ break;
+ }
if (!next_tag.fields.has("path")) {
error = ERR_FILE_CORRUPT;
@@ -430,30 +435,46 @@ Error ResourceInteractiveLoaderText::poll() {
path = remaps[path];
}
- RES res = ResourceLoader::load(path, type);
+ ExtResource er;
+ er.path = path;
+ er.type = type;
- if (res.is_null()) {
+ if (use_sub_threads) {
+ Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, local_path);
- if (ResourceLoader::get_abort_on_missing_resources()) {
- error = ERR_FILE_CORRUPT;
- error_text = "[ext_resource] referenced nonexistent resource at: " + path;
- _printerr();
- return error;
- } else {
- ResourceLoader::notify_dependency_error(local_path, path, type);
+ if (err != OK) {
+ if (ResourceLoader::get_abort_on_missing_resources()) {
+ error = ERR_FILE_CORRUPT;
+ error_text = "[ext_resource] referenced broken resource at: " + path;
+ _printerr();
+ return error;
+ } else {
+ ResourceLoader::notify_dependency_error(local_path, path, type);
+ }
}
+
} else {
+ RES res = ResourceLoader::load(path, type);
- resource_cache.push_back(res);
+ if (res.is_null()) {
+ if (ResourceLoader::get_abort_on_missing_resources()) {
+ error = ERR_FILE_CORRUPT;
+ error_text = "[ext_resource] referenced nonexistent resource at: " + path;
+ _printerr();
+ return error;
+ } else {
+ ResourceLoader::notify_dependency_error(local_path, path, type);
+ }
+ } else {
#ifdef TOOLS_ENABLED
- //remember ID for saving
- res->set_id_for_path(local_path, index);
+ //remember ID for saving
+ res->set_id_for_path(local_path, index);
#endif
+ }
+
+ er.cache = res;
}
- ExtResource er;
- er.path = path;
- er.type = type;
ext_resources[index] = er;
error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp);
@@ -463,9 +484,16 @@ Error ResourceInteractiveLoaderText::poll() {
}
resource_current++;
- return error;
+ }
- } else if (next_tag.name == "sub_resource") {
+ //these are the ones that count
+ resources_total -= resource_current;
+ resource_current = 0;
+
+ while (true) {
+ if (next_tag.name != "sub_resource") {
+ break;
+ }
if (!next_tag.fields.has("type")) {
error = ERR_FILE_CORRUPT;
@@ -490,11 +518,10 @@ Error ResourceInteractiveLoaderText::poll() {
Ref<Resource> res;
- if (!ResourceCache::has(path)) { //only if it doesn't exist
+ if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist
Object *obj = ClassDB::instance(type);
if (!obj) {
-
error_text += "Can't create sub resource of type: " + type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -503,7 +530,6 @@ Error ResourceInteractiveLoaderText::poll() {
Resource *r = Object::cast_to<Resource>(obj);
if (!r) {
-
error_text += "Can't create sub resource of type, because not a resource: " + type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -511,14 +537,15 @@ Error ResourceInteractiveLoaderText::poll() {
}
res = Ref<Resource>(r);
- resource_cache.push_back(res);
- res->set_path(path);
+ int_resources[id] = res;
+ if (!use_nocache) {
+ res->set_path(path);
+ }
}
resource_current++;
while (true) {
-
String assign;
Variant value;
@@ -535,7 +562,6 @@ Error ResourceInteractiveLoaderText::poll() {
}
//it's assignment
} else if (next_tag.name != String()) {
-
error = OK;
break;
} else {
@@ -546,12 +572,17 @@ Error ResourceInteractiveLoaderText::poll() {
}
}
- return OK;
+ if (progress && resources_total > 0) {
+ *progress = resource_current / float(resources_total);
+ }
+ }
- } else if (next_tag.name == "resource") {
+ while (true) {
+ if (next_tag.name != "resource") {
+ break;
+ }
if (is_scene) {
-
error_text += "found the 'resource' tag on a scene file!";
_printerr();
error = ERR_FILE_CORRUPT;
@@ -560,7 +591,6 @@ Error ResourceInteractiveLoaderText::poll() {
Object *obj = ClassDB::instance(res_type);
if (!obj) {
-
error_text += "Can't create sub resource of type: " + res_type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -569,7 +599,6 @@ Error ResourceInteractiveLoaderText::poll() {
Resource *r = Object::cast_to<Resource>(obj);
if (!r) {
-
error_text += "Can't create sub resource of type, because not a resource: " + res_type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -581,7 +610,6 @@ Error ResourceInteractiveLoaderText::poll() {
resource_current++;
while (true) {
-
String assign;
Variant value;
@@ -591,10 +619,13 @@ Error ResourceInteractiveLoaderText::poll() {
if (error != ERR_FILE_EOF) {
_printerr();
} else {
- if (!ResourceCache::has(res_path)) {
- resource->set_path(res_path);
+ error = OK;
+ if (!use_nocache) {
+ if (!ResourceCache::has(res_path)) {
+ resource->set_path(res_path);
+ }
+ resource->set_as_translation_remapped(translation_remapped);
}
- resource->set_as_translation_remapped(translation_remapped);
}
return error;
}
@@ -603,23 +634,25 @@ Error ResourceInteractiveLoaderText::poll() {
resource->set(assign, value);
//it's assignment
} else if (next_tag.name != String()) {
-
error = ERR_FILE_CORRUPT;
error_text = "Extra tag found when parsing main resource file";
_printerr();
return error;
} else {
- error = ERR_FILE_EOF;
+ error = OK;
+ if (progress && resources_total > 0) {
+ *progress = resource_current / float(resources_total);
+ }
+
return error;
}
}
+ }
- return OK;
-
- } else if (next_tag.name == "node") {
+ //for scene files
+ if (next_tag.name == "node") {
if (!is_scene) {
-
error_text += "found the 'node' tag on a resource file!";
_printerr();
error = ERR_FILE_CORRUPT;
@@ -628,59 +661,68 @@ Error ResourceInteractiveLoaderText::poll() {
Ref<PackedScene> packed_scene = _parse_node_tag(rp);
- if (!packed_scene.is_valid())
+ if (!packed_scene.is_valid()) {
return error;
+ }
- error = ERR_FILE_EOF;
+ error = OK;
//get it here
resource = packed_scene;
- if (!ResourceCache::has(res_path)) {
+ if (!use_nocache && !ResourceCache::has(res_path)) {
packed_scene->set_path(res_path);
}
- return error;
+ resource_current++;
+ if (progress && resources_total > 0) {
+ *progress = resource_current / float(resources_total);
+ }
+
+ return error;
} else {
error_text += "Unknown tag in file: " + next_tag.name;
_printerr();
error = ERR_FILE_CORRUPT;
return error;
}
-
- return OK;
}
-int ResourceInteractiveLoaderText::get_stage() const {
-
+int ResourceLoaderText::get_stage() const {
return resource_current;
}
-int ResourceInteractiveLoaderText::get_stage_count() const {
+int ResourceLoaderText::get_stage_count() const {
return resources_total; //+ext_resources;
}
-void ResourceInteractiveLoaderText::set_translation_remapped(bool p_remapped) {
-
+void ResourceLoaderText::set_translation_remapped(bool p_remapped) {
translation_remapped = p_remapped;
}
-ResourceInteractiveLoaderText::ResourceInteractiveLoaderText() {
+ResourceLoaderText::ResourceLoaderText() {
+ use_nocache = false;
+
+ resources_total = 0;
+ resource_current = 0;
+ use_sub_threads = false;
+
+ progress = nullptr;
+ lines = false;
translation_remapped = false;
+ use_sub_threads = false;
+ error = OK;
}
-ResourceInteractiveLoaderText::~ResourceInteractiveLoaderText() {
-
+ResourceLoaderText::~ResourceLoaderText() {
memdelete(f);
}
-void ResourceInteractiveLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
-
+void ResourceLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
open(p_f);
ignore_resource_parsing = true;
ERR_FAIL_COND(error != OK);
while (next_tag.name == "ext_resource") {
-
if (!next_tag.fields.has("type")) {
error = ERR_FILE_CORRUPT;
error_text = "Missing 'type' in external resource tag";
@@ -720,21 +762,19 @@ void ResourceInteractiveLoaderText::get_dependencies(FileAccess *p_f, List<Strin
}
}
-Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map) {
-
+Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map) {
open(p_f, true);
ERR_FAIL_COND_V(error != OK, error);
ignore_resource_parsing = true;
//FileAccess
- FileAccess *fw = NULL;
+ FileAccess *fw = nullptr;
String base_path = local_path.get_base_dir();
uint64_t tag_end = f->get_position();
while (true) {
-
Error err = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp);
if (err != OK) {
@@ -746,17 +786,15 @@ Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const
}
if (next_tag.name != "ext_resource") {
-
//nothing was done
- if (!fw)
+ if (!fw) {
return OK;
+ }
break;
} else {
-
if (!fw) {
-
fw = FileAccess::open(p_path + ".depren", FileAccess::WRITE);
if (is_scene) {
fw->store_line("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
@@ -822,8 +860,7 @@ Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const
return OK;
}
-void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) {
-
+void ResourceLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) {
error = OK;
lines = 1;
@@ -838,7 +875,6 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag)
Error err = VariantParser::parse_tag(&stream, lines, error_text, tag);
if (err) {
-
error = err;
_printerr();
return;
@@ -881,7 +917,6 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag)
}
if (!p_skip_first_tag) {
-
err = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp);
if (err) {
@@ -893,12 +928,11 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag)
rp.ext_func = _parse_ext_resources;
rp.sub_func = _parse_sub_resources;
- rp.func = NULL;
+ rp.func = nullptr;
rp.userdata = this;
}
static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false) {
-
CharString utf8 = p_string.utf8();
if (p_bit_on_len) {
f->store_32((utf8.length() + 1) | 0x80000000);
@@ -908,10 +942,10 @@ static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p
f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
}
-Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) {
-
- if (error)
+Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) {
+ if (error) {
return error;
+ }
FileAccessRef wf = FileAccess::open(p_path, FileAccess::WRITE);
if (!wf) {
@@ -931,8 +965,9 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
bs_save_unicode_string(wf.f, is_scene ? "PackedScene" : resource_type);
wf->store_64(0); //offset to import metadata, this is no longer used
- for (int i = 0; i < 14; i++)
+ for (int i = 0; i < 14; i++) {
wf->store_32(0); // reserved
+ }
wf->store_32(0); //string table size, will not be in use
size_t ext_res_count_pos = wf->get_position();
@@ -948,7 +983,6 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
rp.userdata = &dummy_read;
while (next_tag.name == "ext_resource") {
-
if (!next_tag.fields.has("path")) {
error = ERR_FILE_CORRUPT;
error_text = "Missing 'path' in external resource tag";
@@ -1012,7 +1046,6 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
Vector<size_t> local_pointers_pos;
while (next_tag.name == "sub_resource" || next_tag.name == "resource") {
-
String type;
int id = -1;
bool main_res;
@@ -1054,7 +1087,6 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
int prop_count = 0;
while (true) {
-
String assign;
Variant value;
@@ -1071,14 +1103,12 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
}
if (assign != String()) {
-
Map<StringName, int> empty_string_map; //unused
bs_save_unicode_string(wf2, assign, true);
ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map);
prop_count++;
} else if (next_tag.name != String()) {
-
error = OK;
break;
} else {
@@ -1098,7 +1128,6 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
//this is a node, must save one more!
if (!is_scene) {
-
error_text += "found the 'node' tag on a resource file!";
_printerr();
error = ERR_FILE_CORRUPT;
@@ -1107,8 +1136,9 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
Ref<PackedScene> packed_scene = _parse_node_tag(rp);
- if (!packed_scene.is_valid())
+ if (!packed_scene.is_valid()) {
return error;
+ }
error = OK;
//get it here
@@ -1127,9 +1157,9 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
int prop_count = 0;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
String name = E->get().name;
Variant value = packed_scene->get(name);
@@ -1172,8 +1202,7 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin
return OK;
}
-String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) {
-
+String ResourceLoaderText::recognize(FileAccess *p_f) {
error = OK;
lines = 1;
@@ -1200,11 +1229,13 @@ String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) {
}
}
- if (tag.name == "gd_scene")
+ if (tag.name == "gd_scene") {
return "PackedScene";
+ }
- if (tag.name != "gd_resource")
+ if (tag.name != "gd_resource") {
return "";
+ }
if (!tag.fields.has("type")) {
error_text = "Missing 'type' field in 'gd_resource' tag";
@@ -1217,119 +1248,123 @@ String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) {
/////////////////////
-Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
-
- if (r_error)
+RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
Error err;
+
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- ERR_FAIL_COND_V_MSG(err != OK, Ref<ResourceInteractiveLoader>(), "Cannot open file '" + p_path + "'.");
+ ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'.");
- Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText);
+ ResourceLoaderText loader;
String path = p_original_path != "" ? p_original_path : p_path;
- ria->local_path = ProjectSettings::get_singleton()->localize_path(path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
- ria->open(f);
-
- return ria;
+ loader.use_nocache = p_no_cache;
+ loader.use_sub_threads = p_use_sub_threads;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
+ loader.progress = r_progress;
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
+ loader.open(f);
+ err = loader.load();
+ if (r_error) {
+ *r_error = err;
+ }
+ if (err == OK) {
+ return loader.get_resource();
+ } else {
+ return RES();
+ }
}
void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
-
if (p_type == "") {
get_recognized_extensions(p_extensions);
return;
}
- if (p_type == "PackedScene")
+ if (p_type == "PackedScene") {
p_extensions->push_back("tscn");
- else
+ } else {
p_extensions->push_back("tres");
+ }
}
void ResourceFormatLoaderText::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("tscn");
p_extensions->push_back("tres");
}
bool ResourceFormatLoaderText::handles_type(const String &p_type) const {
-
return true;
}
-String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
+String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
String ext = p_path.get_extension().to_lower();
- if (ext == "tscn")
+ if (ext == "tscn") {
return "PackedScene";
- else if (ext != "tres")
+ } else if (ext != "tres") {
return String();
+ }
//for anyhting else must test..
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
-
return ""; //could not rwead
}
- Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
- String r = ria->recognize(f);
- return r;
+ ResourceLoaderText loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
+ String r = loader.recognize(f);
+ return ClassDB::get_compatibility_remapped_class(r);
}
void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
-
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
-
ERR_FAIL();
}
- Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
- ria->get_dependencies(f, p_dependencies, p_add_types);
+ ResourceLoaderText loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
+ loader.get_dependencies(f, p_dependencies, p_add_types);
}
Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
-
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
-
ERR_FAIL_V(ERR_CANT_OPEN);
}
- Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
- return ria->rename_dependencies(f, p_path, p_map);
+ ResourceLoaderText loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
+ return loader.rename_dependencies(f, p_path, p_map);
}
-ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = NULL;
+ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = nullptr;
Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &p_dst_path) {
-
Error err;
FileAccess *f = FileAccess::open(p_src_path, FileAccess::READ, &err);
ERR_FAIL_COND_V_MSG(err != OK, ERR_CANT_OPEN, "Cannot open file '" + p_src_path + "'.");
- Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText);
+ ResourceLoaderText loader;
const String &path = p_src_path;
- ria->local_path = ProjectSettings::get_singleton()->localize_path(path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
- ria->open(f);
- return ria->save_as_binary(f, p_dst_path);
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
+ loader.open(f);
+ return loader.save_as_binary(f, p_dst_path);
}
/*****************************************************************************************************/
@@ -1344,18 +1379,14 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path,
/*****************************************************************************************************/
String ResourceFormatSaverTextInstance::_write_resources(void *ud, const RES &p_resource) {
-
ResourceFormatSaverTextInstance *rsi = (ResourceFormatSaverTextInstance *)ud;
return rsi->_write_resource(p_resource);
}
String ResourceFormatSaverTextInstance::_write_resource(const RES &res) {
-
if (external_resources.has(res)) {
-
return "ExtResource( " + itos(external_resources[res]) + " )";
} else {
-
if (internal_resources.has(res)) {
return "SubResource( " + itos(internal_resources[res]) + " )";
} else if (res->get_path().length() && res->get_path().find("::") == -1) {
@@ -1373,18 +1404,17 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) {
}
void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, bool p_main) {
-
switch (p_variant.get_type()) {
case Variant::OBJECT: {
+ RES res = p_variant;
- RES res = p_variant.operator RefPtr();
-
- if (res.is_null() || external_resources.has(res))
+ if (res.is_null() || external_resources.has(res)) {
return;
+ }
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
if (res->get_path() == local_path) {
- ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
+ ERR_PRINT("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
return;
}
int index = external_resources.size();
@@ -1392,8 +1422,9 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
return;
}
- if (resource_set.has(res))
+ if (resource_set.has(res)) {
return;
+ }
List<PropertyInfo> property_list;
@@ -1403,11 +1434,9 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
List<PropertyInfo>::Element *I = property_list.front();
while (I) {
-
PropertyInfo pi = I->get();
if (pi.usage & PROPERTY_USAGE_STORAGE) {
-
Variant v = res->get(I->get().name);
if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
@@ -1433,23 +1462,19 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
} break;
case Variant::ARRAY: {
-
Array varray = p_variant;
int len = varray.size();
for (int i = 0; i < len; i++) {
-
const Variant &v = varray.get(i);
_find_resources(v);
}
} break;
case Variant::DICTIONARY: {
-
Dictionary d = p_variant;
List<Variant> keys;
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
Variant v = d[E->get()];
_find_resources(v);
}
@@ -1460,7 +1485,6 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
}
Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
if (p_path.ends_with(".tscn")) {
packed_scene = p_resource;
}
@@ -1486,8 +1510,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
if (packed_scene.is_valid()) {
//add instances to external resources if saving a packed scene
for (int i = 0; i < packed_scene->get_state()->get_node_count(); i++) {
- if (packed_scene->get_state()->is_node_instance_placeholder(i))
+ if (packed_scene->get_state()->is_node_instance_placeholder(i)) {
continue;
+ }
Ref<PackedScene> instance = packed_scene->get_state()->get_node_instance(i);
if (instance.is_valid() && !external_resources.has(instance)) {
@@ -1499,8 +1524,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
{
String title = packed_scene.is_valid() ? "[gd_scene " : "[gd_resource ";
- if (packed_scene.is_null())
+ if (packed_scene.is_null()) {
title += "type=\"" + p_resource->get_class() + "\" ";
+ }
int load_steps = saved_resources.size() + external_resources.size();
/*
if (packed_scene.is_valid()) {
@@ -1557,7 +1583,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
Vector<ResourceSort> sorted_er;
for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
-
ResourceSort rs;
rs.resource = E->key();
rs.index = E->get();
@@ -1572,16 +1597,15 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string("[ext_resource path=\"" + p + "\" type=\"" + sorted_er[i].resource->get_save_class() + "\" id=" + itos(sorted_er[i].index) + "]\n"); //bundled
}
- if (external_resources.size())
+ if (external_resources.size()) {
f->store_line(String()); //separate
+ }
Set<int> used_indices;
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
-
RES res = E->get();
if (E->next() && (res->get_path() == "" || res->get_path().find("::") != -1)) {
-
if (res->get_subindex() != 0) {
if (used_indices.has(res->get_subindex())) {
res->set_subindex(0); //repeated
@@ -1593,13 +1617,13 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
-
RES res = E->get();
ERR_CONTINUE(!resource_set.has(res));
- bool main = (E->next() == NULL);
+ bool main = (E->next() == nullptr);
- if (main && packed_scene.is_valid())
+ if (main && packed_scene.is_valid()) {
break; //save as a scene
+ }
if (main) {
f->store_line("[resource]");
@@ -1632,12 +1656,11 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
res->get_property_list(&property_list);
//property_list.sort();
for (List<PropertyInfo>::Element *PE = property_list.front(); PE; PE = PE->next()) {
-
- if (skip_editor && PE->get().name.begins_with("__editor"))
+ if (skip_editor && PE->get().name.begins_with("__editor")) {
continue;
+ }
if (PE->get().usage & PROPERTY_USAGE_STORAGE) {
-
String name = PE->get().name;
Variant value;
if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
@@ -1656,8 +1679,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
continue;
}
- if (PE->get().type == Variant::OBJECT && value.is_zero() && !(PE->get().usage & PROPERTY_USAGE_STORE_IF_NULL))
+ if (PE->get().type == Variant::OBJECT && value.is_zero() && !(PE->get().usage & PROPERTY_USAGE_STORE_IF_NULL)) {
continue;
+ }
String vars;
VariantWriter::write_to_string(value, vars, _write_resources, this);
@@ -1665,15 +1689,15 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
}
- if (E->next())
+ if (E->next()) {
f->store_line(String());
+ }
}
if (packed_scene.is_valid()) {
//if this is a scene, save nodes and connections!
Ref<SceneState> state = packed_scene->get_state();
for (int i = 0; i < state->get_node_count(); i++) {
-
StringName type = state->get_node_type(i);
StringName name = state->get_node_name(i);
int index = state->get_node_index(i);
@@ -1711,7 +1735,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string(header);
if (instance_placeholder != String()) {
-
String vars;
f->store_string(" instance_placeholder=");
VariantWriter::write_to_string(instance_placeholder, vars, _write_resources, this);
@@ -1719,7 +1742,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
if (instance.is_valid()) {
-
String vars;
f->store_string(" instance=");
VariantWriter::write_to_string(instance, vars, _write_resources, this);
@@ -1729,19 +1751,18 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_line("]");
for (int j = 0; j < state->get_node_property_count(i); j++) {
-
String vars;
VariantWriter::write_to_string(state->get_node_property_value(i, j), vars, _write_resources, this);
f->store_string(String(state->get_node_property_name(i, j)).property_name_encode() + " = " + vars + "\n");
}
- if (i < state->get_node_count() - 1)
+ if (i < state->get_node_count() - 1) {
f->store_line(String());
+ }
}
for (int i = 0; i < state->get_connection_count(); i++) {
-
String connstr = "[connection";
connstr += " signal=\"" + String(state->get_connection_signal(i)) + "\"";
connstr += " from=\"" + String(state->get_connection_source(i).simplified()) + "\"";
@@ -1781,7 +1802,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
Error ResourceFormatSaverText::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
if (p_path.ends_with(".sct") && p_resource->get_class() != "PackedScene") {
return ERR_FILE_UNRECOGNIZED;
}
@@ -1791,18 +1811,18 @@ Error ResourceFormatSaverText::save(const String &p_path, const RES &p_resource,
}
bool ResourceFormatSaverText::recognize(const RES &p_resource) const {
-
return true; // all recognized!
}
-void ResourceFormatSaverText::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
- if (p_resource->get_class() == "PackedScene")
+void ResourceFormatSaverText::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+ if (p_resource->get_class() == "PackedScene") {
p_extensions->push_back("tscn"); //text scene
- else
+ } else {
p_extensions->push_back("tres"); //text resource
+ }
}
-ResourceFormatSaverText *ResourceFormatSaverText::singleton = NULL;
+ResourceFormatSaverText *ResourceFormatSaverText::singleton = nullptr;
ResourceFormatSaverText::ResourceFormatSaverText() {
singleton = this;
}
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index 66c69725e8..cf522c9364 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -37,8 +37,7 @@
#include "core/variant_parser.h"
#include "scene/resources/packed_scene.h"
-class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
-
+class ResourceLoaderText {
bool translation_remapped;
String local_path;
String res_path;
@@ -49,6 +48,7 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
VariantParser::StreamFile stream;
struct ExtResource {
+ RES cache;
String path;
String type;
};
@@ -61,6 +61,7 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
//Map<String,String> remaps;
Map<int, ExtResource> ext_resources;
+ Map<int, RES> int_resources;
int resources_total;
int resource_current;
@@ -68,13 +69,18 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
VariantParser::Tag next_tag;
+ bool use_nocache;
+
+ bool use_sub_threads;
+ float *progress;
+
mutable int lines;
Map<String, String> remaps;
//void _printerr();
- static Error _parse_sub_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText *>(p_self)->_parse_sub_resource(p_stream, r_res, line, r_err_str); }
- static Error _parse_ext_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText *>(p_self)->_parse_ext_resource(p_stream, r_res, line, r_err_str); }
+ static Error _parse_sub_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceLoaderText *>(p_self)->_parse_sub_resource(p_stream, r_res, line, r_err_str); }
+ static Error _parse_ext_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceLoaderText *>(p_self)->_parse_ext_resource(p_stream, r_res, line, r_err_str); }
Error _parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str);
Error _parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str);
@@ -85,7 +91,6 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
};
struct DummyReadData {
-
Map<RES, int> external_resources;
Map<int, RES> rev_external_resources;
Set<RES> resource_set;
@@ -102,7 +107,6 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
friend class ResourceFormatLoaderText;
- List<RES> resource_cache;
Error error;
RES resource;
@@ -110,12 +114,12 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
Ref<PackedScene> _parse_node_tag(VariantParser::ResourceParser &parser);
public:
- virtual void set_local_path(const String &p_local_path);
- virtual Ref<Resource> get_resource();
- virtual Error poll();
- virtual int get_stage() const;
- virtual int get_stage_count() const;
- virtual void set_translation_remapped(bool p_remapped);
+ void set_local_path(const String &p_local_path);
+ Ref<Resource> get_resource();
+ Error load();
+ int get_stage() const;
+ int get_stage_count() const;
+ void set_translation_remapped(bool p_remapped);
void open(FileAccess *p_f, bool p_skip_first_tag = false);
String recognize(FileAccess *p_f);
@@ -123,14 +127,14 @@ public:
Error rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map);
Error save_as_binary(FileAccess *p_f, const String &p_path);
- ResourceInteractiveLoaderText();
- ~ResourceInteractiveLoaderText();
+ ResourceLoaderText();
+ ~ResourceLoaderText();
};
class ResourceFormatLoaderText : public ResourceFormatLoader {
public:
static ResourceFormatLoaderText *singleton;
- virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
@@ -144,7 +148,6 @@ public:
};
class ResourceFormatSaverTextInstance {
-
String local_path;
Ref<PackedScene> packed_scene;
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 0070de72a2..b1001203a1 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -30,60 +30,58 @@
#include "segment_shape_2d.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "core/math/geometry_2d.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
bool SegmentShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
Vector2 l[2] = { a, b };
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, l);
+ Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, l);
return p_point.distance_to(closest) < p_tolerance;
}
void SegmentShape2D::_update_shape() {
-
Rect2 r;
r.position = a;
r.size = b;
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), r);
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), r);
emit_changed();
}
void SegmentShape2D::set_a(const Vector2 &p_a) {
-
a = p_a;
_update_shape();
}
-Vector2 SegmentShape2D::get_a() const {
+Vector2 SegmentShape2D::get_a() const {
return a;
}
void SegmentShape2D::set_b(const Vector2 &p_b) {
-
b = p_b;
_update_shape();
}
-Vector2 SegmentShape2D::get_b() const {
+Vector2 SegmentShape2D::get_b() const {
return b;
}
void SegmentShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
- VisualServer::get_singleton()->canvas_item_add_line(p_to_rid, a, b, p_color, 3);
+ RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, a, b, p_color, 3);
}
Rect2 SegmentShape2D::get_rect() const {
-
Rect2 rect;
rect.position = a;
rect.expand_to(b);
return rect;
}
-void SegmentShape2D::_bind_methods() {
+real_t SegmentShape2D::get_enclosing_radius() const {
+ return (a + b).length();
+}
+void SegmentShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_a", "a"), &SegmentShape2D::set_a);
ClassDB::bind_method(D_METHOD("get_a"), &SegmentShape2D::get_a);
@@ -95,85 +93,8 @@ void SegmentShape2D::_bind_methods() {
}
SegmentShape2D::SegmentShape2D() :
- Shape2D(Physics2DServer::get_singleton()->segment_shape_create()) {
-
+ Shape2D(PhysicsServer2D::get_singleton()->segment_shape_create()) {
a = Vector2();
b = Vector2(0, 10);
_update_shape();
}
-
-////////////////////////////////////////////////////////////
-
-void RayShape2D::_update_shape() {
-
- Dictionary d;
- d["length"] = length;
- d["slips_on_slope"] = slips_on_slope;
- Physics2DServer::get_singleton()->shape_set_data(get_rid(), d);
- emit_changed();
-}
-
-void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
- Vector2 tip = Vector2(0, get_length());
- VS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3);
- Vector<Vector2> pts;
- float tsize = 4;
- pts.push_back(tip + Vector2(0, tsize));
- pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0));
- pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++)
- cols.push_back(p_color);
-
- VS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
-}
-
-Rect2 RayShape2D::get_rect() const {
-
- Rect2 rect;
- rect.position = Vector2();
- rect.expand_to(Vector2(0, length));
- rect = rect.grow(Math_SQRT12 * 4);
- return rect;
-}
-
-void RayShape2D::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length);
- ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length);
-
- ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope);
- ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "length"), "set_length", "get_length");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope");
-}
-
-void RayShape2D::set_length(real_t p_length) {
-
- length = p_length;
- _update_shape();
-}
-real_t RayShape2D::get_length() const {
-
- return length;
-}
-
-void RayShape2D::set_slips_on_slope(bool p_active) {
-
- slips_on_slope = p_active;
- _update_shape();
-}
-
-bool RayShape2D::get_slips_on_slope() const {
- return slips_on_slope;
-}
-
-RayShape2D::RayShape2D() :
- Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) {
-
- length = 20;
- slips_on_slope = false;
- _update_shape();
-}
diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h
index aaf838ebfb..31a61ea564 100644
--- a/scene/resources/segment_shape_2d.h
+++ b/scene/resources/segment_shape_2d.h
@@ -45,7 +45,7 @@ protected:
static void _bind_methods();
public:
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
void set_a(const Vector2 &p_a);
void set_b(const Vector2 &p_b);
@@ -53,34 +53,11 @@ public:
Vector2 get_a() const;
Vector2 get_b() const;
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
+ virtual void draw(const RID &p_to_rid, const Color &p_color) override;
+ virtual Rect2 get_rect() const override;
+ virtual real_t get_enclosing_radius() const override;
SegmentShape2D();
};
-class RayShape2D : public Shape2D {
- GDCLASS(RayShape2D, Shape2D);
-
- real_t length;
- bool slips_on_slope;
-
- void _update_shape();
-
-protected:
- static void _bind_methods();
-
-public:
- void set_length(real_t p_length);
- real_t get_length() const;
-
- void set_slips_on_slope(bool p_active);
- bool get_slips_on_slope() const;
-
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
-
- RayShape2D();
-};
-
#endif // SEGMENT_SHAPE_2D_H
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 44c2a46065..92f0353abf 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -31,50 +31,47 @@
#include "shader.h"
#include "core/os/file_access.h"
#include "scene/scene_string_names.h"
-#include "servers/visual/shader_language.h"
-#include "servers/visual_server.h"
+#include "servers/rendering/shader_language.h"
+#include "servers/rendering_server.h"
#include "texture.h"
Shader::Mode Shader::get_mode() const {
-
return mode;
}
void Shader::set_code(const String &p_code) {
-
String type = ShaderLanguage::get_shader_type(p_code);
if (type == "canvas_item") {
mode = MODE_CANVAS_ITEM;
} else if (type == "particles") {
mode = MODE_PARTICLES;
+ } else if (type == "sky") {
+ mode = MODE_SKY;
} else {
mode = MODE_SPATIAL;
}
- VisualServer::get_singleton()->shader_set_code(shader, p_code);
+ RenderingServer::get_singleton()->shader_set_code(shader, p_code);
params_cache_dirty = true;
emit_changed();
}
String Shader::get_code() const {
-
_update_shader();
- return VisualServer::get_singleton()->shader_get_code(shader);
+ return RenderingServer::get_singleton()->shader_get_code(shader);
}
void Shader::get_param_list(List<PropertyInfo> *p_params) const {
-
_update_shader();
List<PropertyInfo> local;
- VisualServer::get_singleton()->shader_get_param_list(shader, &local);
+ RenderingServer::get_singleton()->shader_get_param_list(shader, &local);
params_cache.clear();
params_cache_dirty = false;
for (List<PropertyInfo>::Element *E = local.front(); E; E = E->next()) {
-
PropertyInfo pi = E->get();
if (default_textures.has(pi.name)) { //do not show default textures
continue;
@@ -82,47 +79,43 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const {
pi.name = "shader_param/" + pi.name;
params_cache[pi.name] = E->get().name;
if (p_params) {
-
//small little hack
- if (pi.type == Variant::_RID)
+ if (pi.type == Variant::_RID) {
pi.type = Variant::OBJECT;
+ }
p_params->push_back(pi);
}
}
}
RID Shader::get_rid() const {
-
_update_shader();
return shader;
}
-void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture> &p_texture) {
-
+void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture) {
if (p_texture.is_valid()) {
default_textures[p_param] = p_texture;
- VS::get_singleton()->shader_set_default_texture_param(shader, p_param, p_texture->get_rid());
+ RS::get_singleton()->shader_set_default_texture_param(shader, p_param, p_texture->get_rid());
} else {
default_textures.erase(p_param);
- VS::get_singleton()->shader_set_default_texture_param(shader, p_param, RID());
+ RS::get_singleton()->shader_set_default_texture_param(shader, p_param, RID());
}
emit_changed();
}
-Ref<Texture> Shader::get_default_texture_param(const StringName &p_param) const {
-
- if (default_textures.has(p_param))
+Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) const {
+ if (default_textures.has(p_param)) {
return default_textures[p_param];
- else
- return Ref<Texture>();
+ } else {
+ return Ref<Texture2D>();
+ }
}
void Shader::get_default_texture_param_list(List<StringName> *r_textures) const {
-
- for (const Map<StringName, Ref<Texture> >::Element *E = default_textures.front(); E; E = E->next()) {
-
+ for (const Map<StringName, Ref<Texture2D>>::Element *E = default_textures.front(); E; E = E->next()) {
r_textures->push_back(E->key());
}
}
@@ -132,15 +125,13 @@ bool Shader::is_text_shader() const {
}
bool Shader::has_param(const StringName &p_param) const {
-
- return params_cache.has(p_param);
+ return params_cache.has("shader_param/" + p_param);
}
void Shader::_update_shader() const {
}
void Shader::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_mode"), &Shader::get_mode);
ClassDB::bind_method(D_METHOD("set_code", "code"), &Shader::set_code);
@@ -151,32 +142,30 @@ void Shader::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_param", "name"), &Shader::has_param);
- //ClassDB::bind_method(D_METHOD("get_param_list"),&Shader::get_fragment_code);
-
ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_code", "get_code");
BIND_ENUM_CONSTANT(MODE_SPATIAL);
BIND_ENUM_CONSTANT(MODE_CANVAS_ITEM);
BIND_ENUM_CONSTANT(MODE_PARTICLES);
+ BIND_ENUM_CONSTANT(MODE_SKY);
}
Shader::Shader() {
-
mode = MODE_SPATIAL;
- shader = VisualServer::get_singleton()->shader_create();
+ shader = RenderingServer::get_singleton()->shader_create();
params_cache_dirty = true;
}
Shader::~Shader() {
-
- VisualServer::get_singleton()->free(shader);
+ RenderingServer::get_singleton()->free(shader);
}
-////////////
-RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error) {
+////////////
- if (r_error)
+RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
Ref<Shader> shader;
shader.instance();
@@ -188,32 +177,30 @@ RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_origi
shader->set_code(str);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return shader;
}
void ResourceFormatLoaderShader::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("shader");
}
bool ResourceFormatLoaderShader::handles_type(const String &p_type) const {
-
return (p_type == "Shader");
}
String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "shader")
+ if (el == "shader") {
return "Shader";
+ }
return "";
}
Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Ref<Shader> shader = p_resource;
ERR_FAIL_COND_V(shader.is_null(), ERR_INVALID_PARAMETER);
@@ -236,14 +223,13 @@ Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resourc
}
void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
if (const Shader *shader = Object::cast_to<Shader>(*p_resource)) {
if (shader->is_text_shader()) {
p_extensions->push_back("shader");
}
}
}
-bool ResourceFormatSaverShader::recognize(const RES &p_resource) const {
+bool ResourceFormatSaverShader::recognize(const RES &p_resource) const {
return p_resource->get_class_name() == "Shader"; //only shader, not inherited
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index 67ae436a4c..7dcec7811a 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -37,7 +37,6 @@
#include "scene/resources/texture.h"
class Shader : public Resource {
-
GDCLASS(Shader, Resource);
OBJ_SAVE_TYPE(Shader);
@@ -47,6 +46,7 @@ public:
MODE_SPATIAL,
MODE_CANVAS_ITEM,
MODE_PARTICLES,
+ MODE_SKY,
MODE_MAX
};
@@ -55,11 +55,11 @@ private:
Mode mode;
// hack the name of performance
- // shaders keep a list of ShaderMaterial -> VisualServer name translations, to make
+ // shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make
// conversion fast and save memory.
mutable bool params_cache_dirty;
mutable Map<StringName, StringName> params_cache; //map a shader param to a material param..
- Map<StringName, Ref<Texture> > default_textures;
+ Map<StringName, Ref<Texture2D>> default_textures;
virtual void _update_shader() const; //used for visual shader
protected:
@@ -75,23 +75,25 @@ public:
void get_param_list(List<PropertyInfo> *p_params) const;
bool has_param(const StringName &p_param) const;
- void set_default_texture_param(const StringName &p_param, const Ref<Texture> &p_texture);
- Ref<Texture> get_default_texture_param(const StringName &p_param) const;
+ void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_default_texture_param(const StringName &p_param) const;
void get_default_texture_param_list(List<StringName> *r_textures) const;
virtual bool is_text_shader() const;
_FORCE_INLINE_ StringName remap_param(const StringName &p_param) const {
- if (params_cache_dirty)
- get_param_list(NULL);
+ if (params_cache_dirty) {
+ get_param_list(nullptr);
+ }
const Map<StringName, StringName>::Element *E = params_cache.find(p_param);
- if (E)
+ if (E) {
return E->get();
+ }
return StringName();
}
- virtual RID get_rid() const;
+ virtual RID get_rid() const override;
Shader();
~Shader();
@@ -101,7 +103,7 @@ VARIANT_ENUM_CAST(Shader::Mode);
class ResourceFormatLoaderShader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp
index 9e97c65a3c..94cecc76eb 100644
--- a/scene/resources/shape_2d.cpp
+++ b/scene/resources/shape_2d.cpp
@@ -29,45 +29,41 @@
/*************************************************************************/
#include "shape_2d.h"
-#include "servers/physics_2d_server.h"
+#include "servers/physics_server_2d.h"
RID Shape2D::get_rid() const {
-
return shape;
}
void Shape2D::set_custom_solver_bias(real_t p_bias) {
-
custom_bias = p_bias;
- Physics2DServer::get_singleton()->shape_set_custom_solver_bias(shape, custom_bias);
+ PhysicsServer2D::get_singleton()->shape_set_custom_solver_bias(shape, custom_bias);
}
real_t Shape2D::get_custom_solver_bias() const {
-
return custom_bias;
}
bool Shape2D::collide_with_motion(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) {
-
ERR_FAIL_COND_V(p_shape.is_null(), false);
int r;
- return Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, NULL, 0, r);
+ return PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, nullptr, 0, r);
}
bool Shape2D::collide(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) {
ERR_FAIL_COND_V(p_shape.is_null(), false);
int r;
- return Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), NULL, 0, r);
+ return PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), nullptr, 0, r);
}
Array Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) {
-
ERR_FAIL_COND_V(p_shape.is_null(), Array());
const int max_contacts = 16;
Vector2 result[max_contacts * 2];
int contacts = 0;
- if (!Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, result, max_contacts, contacts))
+ if (!PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, result, max_contacts, contacts)) {
return Array();
+ }
Array results;
results.resize(contacts * 2);
@@ -77,15 +73,16 @@ Array Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_x
return results;
}
-Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) {
+Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) {
ERR_FAIL_COND_V(p_shape.is_null(), Array());
const int max_contacts = 16;
Vector2 result[max_contacts * 2];
int contacts = 0;
- if (!Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), result, max_contacts, contacts))
+ if (!PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), result, max_contacts, contacts)) {
return Array();
+ }
Array results;
results.resize(contacts * 2);
@@ -97,15 +94,15 @@ Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const
}
void Shape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_custom_solver_bias", "bias"), &Shape2D::set_custom_solver_bias);
ClassDB::bind_method(D_METHOD("get_custom_solver_bias"), &Shape2D::get_custom_solver_bias);
ClassDB::bind_method(D_METHOD("collide", "local_xform", "with_shape", "shape_xform"), &Shape2D::collide);
ClassDB::bind_method(D_METHOD("collide_with_motion", "local_xform", "local_motion", "with_shape", "shape_xform", "shape_motion"), &Shape2D::collide_with_motion);
ClassDB::bind_method(D_METHOD("collide_and_get_contacts", "local_xform", "with_shape", "shape_xform"), &Shape2D::collide_and_get_contacts);
ClassDB::bind_method(D_METHOD("collide_with_motion_and_get_contacts", "local_xform", "local_motion", "with_shape", "shape_xform", "shape_motion"), &Shape2D::collide_with_motion_and_get_contacts);
+ ClassDB::bind_method(D_METHOD("draw", "canvas_item", "color"), &Shape2D::draw);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias");
}
Shape2D::Shape2D(const RID &p_rid) {
@@ -114,6 +111,5 @@ Shape2D::Shape2D(const RID &p_rid) {
}
Shape2D::~Shape2D() {
-
- Physics2DServer::get_singleton()->free(shape);
+ PhysicsServer2D::get_singleton()->free(shape);
}
diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h
index 13ad7492ae..bb4688a02d 100644
--- a/scene/resources/shape_2d.h
+++ b/scene/resources/shape_2d.h
@@ -58,7 +58,9 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color) {}
virtual Rect2 get_rect() const { return Rect2(); }
- virtual RID get_rid() const;
+ /// Returns the radius of a circle that fully enclose this shape
+ virtual real_t get_enclosing_radius() const = 0;
+ virtual RID get_rid() const override;
Shape2D();
~Shape2D();
};
diff --git a/scene/resources/shape.cpp b/scene/resources/shape_3d.cpp
index b50c68727a..59766f4f1f 100644
--- a/scene/resources/shape.cpp
+++ b/scene/resources/shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* shape.cpp */
+/* shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,41 +28,39 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "shape.h"
+#include "shape_3d.h"
#include "core/os/os.h"
#include "scene/main/scene_tree.h"
#include "scene/resources/mesh.h"
-#include "servers/physics_server.h"
-
-void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform) {
+#include "servers/physics_server_3d.h"
+void Shape3D::add_vertices_to_array(Vector<Vector3> &array, const Transform &p_xform) {
Vector<Vector3> toadd = get_debug_mesh_lines();
if (toadd.size()) {
-
int base = array.size();
array.resize(base + toadd.size());
- PoolVector<Vector3>::Write w = array.write();
+ Vector3 *w = array.ptrw();
for (int i = 0; i < toadd.size(); i++) {
w[i + base] = p_xform.xform(toadd[i]);
}
}
}
-real_t Shape::get_margin() const {
+real_t Shape3D::get_margin() const {
return margin;
}
-void Shape::set_margin(real_t p_margin) {
+void Shape3D::set_margin(real_t p_margin) {
margin = p_margin;
- PhysicsServer::get_singleton()->shape_set_margin(shape, margin);
+ PhysicsServer3D::get_singleton()->shape_set_margin(shape, margin);
}
-Ref<ArrayMesh> Shape::get_debug_mesh() {
-
- if (debug_mesh_cache.is_valid())
+Ref<ArrayMesh> Shape3D::get_debug_mesh() {
+ if (debug_mesh_cache.is_valid()) {
return debug_mesh_cache;
+ }
Vector<Vector3> lines = get_debug_mesh_lines();
@@ -70,11 +68,10 @@ Ref<ArrayMesh> Shape::get_debug_mesh() {
if (!lines.empty()) {
//make mesh
- PoolVector<Vector3> array;
+ Vector<Vector3> array;
array.resize(lines.size());
{
-
- PoolVector<Vector3>::Write w = array.write();
+ Vector3 *w = array.ptrw();
for (int i = 0; i < lines.size(); i++) {
w[i] = lines[i];
}
@@ -96,32 +93,25 @@ Ref<ArrayMesh> Shape::get_debug_mesh() {
return debug_mesh_cache;
}
-void Shape::_update_shape() {
+void Shape3D::_update_shape() {
emit_changed();
debug_mesh_cache.unref();
}
-void Shape::_bind_methods() {
+void Shape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape3D::set_margin);
+ ClassDB::bind_method(D_METHOD("get_margin"), &Shape3D::get_margin);
- ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape::set_margin);
- ClassDB::bind_method(D_METHOD("get_margin"), &Shape::get_margin);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin");
}
-Shape::Shape() :
- margin(0.04) {
-
- ERR_PRINT("Constructor must not be called!");
-}
-
-Shape::Shape(RID p_shape) :
- margin(0.04) {
-
- shape = p_shape;
+Shape3D::Shape3D() {
+ ERR_PRINT("Default constructor must not be called!");
}
-Shape::~Shape() {
+Shape3D::Shape3D(RID p_shape) :
+ shape(p_shape) {}
- PhysicsServer::get_singleton()->free(shape);
+Shape3D::~Shape3D() {
+ PhysicsServer3D::get_singleton()->free(shape);
}
diff --git a/scene/resources/shape.h b/scene/resources/shape_3d.h
index 8fc265f3bc..eb9607e3a6 100644
--- a/scene/resources/shape.h
+++ b/scene/resources/shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* shape.h */
+/* shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,19 +28,19 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SHAPE_H
-#define SHAPE_H
+#ifndef SHAPE_3D_H
+#define SHAPE_3D_H
#include "core/resource.h"
-class ArrayMesh;
-class Shape : public Resource {
+class ArrayMesh;
- GDCLASS(Shape, Resource);
- OBJ_SAVE_TYPE(Shape);
+class Shape3D : public Resource {
+ GDCLASS(Shape3D, Resource);
+ OBJ_SAVE_TYPE(Shape3D);
RES_BASE_EXTENSION("shape");
RID shape;
- real_t margin;
+ real_t margin = 0.04;
Ref<ArrayMesh> debug_mesh_cache;
@@ -48,23 +48,25 @@ protected:
static void _bind_methods();
_FORCE_INLINE_ RID get_shape() const { return shape; }
- Shape(RID p_shape);
+ Shape3D(RID p_shape);
virtual void _update_shape();
public:
- virtual RID get_rid() const { return shape; }
+ virtual RID get_rid() const override { return shape; }
Ref<ArrayMesh> get_debug_mesh();
- virtual Vector<Vector3> get_debug_mesh_lines() = 0; // { return Vector<Vector3>(); }
+ virtual Vector<Vector3> get_debug_mesh_lines() const = 0; // { return Vector<Vector3>(); }
+ /// Returns the radius of a sphere that fully enclose this shape
+ virtual real_t get_enclosing_radius() const = 0;
- void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform);
+ void add_vertices_to_array(Vector<Vector3> &array, const Transform &p_xform);
real_t get_margin() const;
void set_margin(real_t p_margin);
- Shape();
- ~Shape();
+ Shape3D();
+ ~Shape3D();
};
#endif // SHAPE_H
diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp
index 9c8710a59c..e88841a531 100644
--- a/scene/resources/skin.cpp
+++ b/scene/resources/skin.cpp
@@ -45,6 +45,23 @@ void Skin::add_bind(int p_bone, const Transform &p_pose) {
set_bind_pose(index, p_pose);
}
+void Skin::add_named_bind(const String &p_name, const Transform &p_pose) {
+ uint32_t index = bind_count;
+ set_bind_count(bind_count + 1);
+ set_bind_name(index, p_name);
+ set_bind_pose(index, p_pose);
+}
+
+void Skin::set_bind_name(int p_index, const StringName &p_name) {
+ ERR_FAIL_INDEX(p_index, bind_count);
+ bool notify_change = (binds_ptr[p_index].name != StringName()) != (p_name != StringName());
+ binds_ptr[p_index].name = p_name;
+ emit_changed();
+ if (notify_change) {
+ _change_notify();
+ }
+}
+
void Skin::set_bind_bone(int p_index, int p_bone) {
ERR_FAIL_INDEX(p_index, bind_count);
binds_ptr[p_index].bone = p_bone;
@@ -75,6 +92,9 @@ bool Skin::_set(const StringName &p_name, const Variant &p_value) {
if (what == "bone") {
set_bind_bone(index, p_value);
return true;
+ } else if (what == "name") {
+ set_bind_name(index, p_value);
+ return true;
} else if (what == "pose") {
set_bind_pose(index, p_value);
return true;
@@ -84,7 +104,6 @@ bool Skin::_set(const StringName &p_name, const Variant &p_value) {
}
bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name == "bind_count") {
r_ret = get_bind_count();
@@ -95,6 +114,9 @@ bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
if (what == "bone") {
r_ret = get_bind_bone(index);
return true;
+ } else if (what == "name") {
+ r_ret = get_bind_name(index);
+ return true;
} else if (what == "pose") {
r_ret = get_bind_pose(index);
return true;
@@ -102,16 +124,17 @@ bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
}
return false;
}
+
void Skin::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "bind_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"));
for (int i = 0; i < get_bind_count(); i++) {
- p_list->push_back(PropertyInfo(Variant::INT, "bind/" + itos(i) + "/bone", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"));
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bind/" + itos(i) + "/name"));
+ p_list->push_back(PropertyInfo(Variant::INT, "bind/" + itos(i) + "/bone", PROPERTY_HINT_RANGE, "0,16384,1,or_greater", get_bind_name(i) != StringName() ? PROPERTY_USAGE_NOEDITOR : PROPERTY_USAGE_DEFAULT));
p_list->push_back(PropertyInfo(Variant::TRANSFORM, "bind/" + itos(i) + "/pose"));
}
}
void Skin::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_bind_count", "bind_count"), &Skin::set_bind_count);
ClassDB::bind_method(D_METHOD("get_bind_count"), &Skin::get_bind_count);
@@ -120,6 +143,9 @@ void Skin::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bind_pose", "bind_index", "pose"), &Skin::set_bind_pose);
ClassDB::bind_method(D_METHOD("get_bind_pose", "bind_index"), &Skin::get_bind_pose);
+ ClassDB::bind_method(D_METHOD("set_bind_name", "bind_index", "name"), &Skin::set_bind_name);
+ ClassDB::bind_method(D_METHOD("get_bind_name", "bind_index"), &Skin::get_bind_name);
+
ClassDB::bind_method(D_METHOD("set_bind_bone", "bind_index", "bone"), &Skin::set_bind_bone);
ClassDB::bind_method(D_METHOD("get_bind_bone", "bind_index"), &Skin::get_bind_bone);
diff --git a/scene/resources/skin.h b/scene/resources/skin.h
index ddc7c655f5..57aaf1afd4 100644
--- a/scene/resources/skin.h
+++ b/scene/resources/skin.h
@@ -37,7 +37,8 @@ class Skin : public Resource {
GDCLASS(Skin, Resource)
struct Bind {
- int bone;
+ int bone = -1;
+ StringName name;
Transform pose;
};
@@ -58,9 +59,11 @@ public:
inline int get_bind_count() const { return bind_count; }
void add_bind(int p_bone, const Transform &p_pose);
+ void add_named_bind(const String &p_name, const Transform &p_pose);
void set_bind_bone(int p_index, int p_bone);
void set_bind_pose(int p_index, const Transform &p_pose);
+ void set_bind_name(int p_index, const StringName &p_name);
inline int get_bind_bone(int p_index) const {
#ifdef DEBUG_ENABLED
@@ -69,6 +72,13 @@ public:
return binds_ptr[p_index].bone;
}
+ inline StringName get_bind_name(int p_index) const {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_INDEX_V(p_index, bind_count, StringName());
+#endif
+ return binds_ptr[p_index].name;
+ }
+
inline Transform get_bind_pose(int p_index) const {
#ifdef DEBUG_ENABLED
ERR_FAIL_INDEX_V(p_index, bind_count, Transform());
diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp
index c20fbb4129..7e32516f94 100644
--- a/scene/resources/sky.cpp
+++ b/scene/resources/sky.cpp
@@ -36,551 +36,77 @@ void Sky::set_radiance_size(RadianceSize p_size) {
ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX);
radiance_size = p_size;
- _radiance_changed();
-}
-
-Sky::RadianceSize Sky::get_radiance_size() const {
-
- return radiance_size;
-}
-
-void Sky::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size);
- ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size");
-
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_32);
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_64);
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_128);
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_256);
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_512);
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024);
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048);
- BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX);
-}
-
-Sky::Sky() {
- radiance_size = RADIANCE_SIZE_128;
-}
-
-/////////////////////////////////////////
-
-void PanoramaSky::_radiance_changed() {
-
- if (panorama.is_valid()) {
- static const int size[RADIANCE_SIZE_MAX] = {
- 32, 64, 128, 256, 512, 1024, 2048
- };
- VS::get_singleton()->sky_set_texture(sky, panorama->get_rid(), size[get_radiance_size()]);
- }
-}
-
-void PanoramaSky::set_panorama(const Ref<Texture> &p_panorama) {
-
- panorama = p_panorama;
-
- if (panorama.is_valid()) {
-
- _radiance_changed();
-
- } else {
- VS::get_singleton()->sky_set_texture(sky, RID(), 0);
- }
-}
-
-Ref<Texture> PanoramaSky::get_panorama() const {
-
- return panorama;
-}
-
-RID PanoramaSky::get_rid() const {
-
- return sky;
-}
-
-void PanoramaSky::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSky::set_panorama);
- ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSky::get_panorama);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_panorama", "get_panorama");
-}
-
-PanoramaSky::PanoramaSky() {
-
- sky = VS::get_singleton()->sky_create();
-}
-
-PanoramaSky::~PanoramaSky() {
-
- VS::get_singleton()->free(sky);
-}
-//////////////////////////////////
-
-void ProceduralSky::_radiance_changed() {
-
- if (update_queued)
- return; //do nothing yet
-
static const int size[RADIANCE_SIZE_MAX] = {
32, 64, 128, 256, 512, 1024, 2048
};
- VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]);
-}
-
-Ref<Image> ProceduralSky::_generate_sky() {
-
- update_queued = false;
-
- PoolVector<uint8_t> imgdata;
-
- static const int size[TEXTURE_SIZE_MAX] = {
- 256, 512, 1024, 2048, 4096
- };
-
- int w = size[texture_size];
- int h = w / 2;
-
- imgdata.resize(w * h * 4); //RGBE
-
- {
- PoolVector<uint8_t>::Write dataw = imgdata.write();
-
- uint32_t *ptr = (uint32_t *)dataw.ptr();
-
- Color sky_top_linear = sky_top_color.to_linear();
- Color sky_horizon_linear = sky_horizon_color.to_linear();
-
- Color ground_bottom_linear = ground_bottom_color.to_linear();
- Color ground_horizon_linear = ground_horizon_color.to_linear();
-
- Color sun_linear;
- sun_linear.r = sun_color.r * sun_energy;
- sun_linear.g = sun_color.g * sun_energy;
- sun_linear.b = sun_color.b * sun_energy;
-
- Vector3 sun(0, 0, -1);
-
- sun = Basis(Vector3(1, 0, 0), Math::deg2rad(sun_latitude)).xform(sun);
- sun = Basis(Vector3(0, 1, 0), Math::deg2rad(sun_longitude)).xform(sun);
-
- sun.normalize();
-
- for (int i = 0; i < w; i++) {
-
- float u = float(i) / (w - 1);
- float phi = u * 2.0 * Math_PI;
-
- for (int j = 0; j < h; j++) {
-
- float v = float(j) / (h - 1);
- float theta = v * Math_PI;
-
- Vector3 normal(
- Math::sin(phi) * Math::sin(theta) * -1.0,
- Math::cos(theta),
- Math::cos(phi) * Math::sin(theta) * -1.0);
-
- normal.normalize();
-
- float v_angle = Math::acos(CLAMP(normal.y, -1.0, 1.0));
-
- Color color;
-
- if (normal.y < 0) {
- //ground
-
- float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5);
- color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve));
- color.r *= ground_energy;
- color.g *= ground_energy;
- color.b *= ground_energy;
- } else {
- float c = v_angle / (Math_PI * 0.5);
- color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve));
- color.r *= sky_energy;
- color.g *= sky_energy;
- color.b *= sky_energy;
-
- float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0)));
-
- if (sun_angle < sun_angle_min) {
- color = color.blend(sun_linear);
- } else if (sun_angle < sun_angle_max) {
-
- float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);
- c2 = Math::ease(c2, sun_curve);
-
- color = color.blend(sun_linear).linear_interpolate(color, c2);
- }
- }
-
- ptr[j * w + i] = color.to_rgbe9995();
- }
- }
- }
-
- Ref<Image> image;
- image.instance();
- image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata);
-
- return image;
-}
-
-void ProceduralSky::set_sky_top_color(const Color &p_sky_top) {
-
- sky_top_color = p_sky_top;
- _queue_update();
-}
-
-Color ProceduralSky::get_sky_top_color() const {
-
- return sky_top_color;
+ RS::get_singleton()->sky_set_radiance_size(sky, size[radiance_size]);
}
-void ProceduralSky::set_sky_horizon_color(const Color &p_sky_horizon) {
-
- sky_horizon_color = p_sky_horizon;
- _queue_update();
-}
-Color ProceduralSky::get_sky_horizon_color() const {
-
- return sky_horizon_color;
-}
-
-void ProceduralSky::set_sky_curve(float p_curve) {
-
- sky_curve = p_curve;
- _queue_update();
-}
-float ProceduralSky::get_sky_curve() const {
-
- return sky_curve;
-}
-
-void ProceduralSky::set_sky_energy(float p_energy) {
-
- sky_energy = p_energy;
- _queue_update();
-}
-float ProceduralSky::get_sky_energy() const {
-
- return sky_energy;
-}
-
-void ProceduralSky::set_ground_bottom_color(const Color &p_ground_bottom) {
-
- ground_bottom_color = p_ground_bottom;
- _queue_update();
-}
-Color ProceduralSky::get_ground_bottom_color() const {
-
- return ground_bottom_color;
-}
-
-void ProceduralSky::set_ground_horizon_color(const Color &p_ground_horizon) {
-
- ground_horizon_color = p_ground_horizon;
- _queue_update();
-}
-Color ProceduralSky::get_ground_horizon_color() const {
-
- return ground_horizon_color;
-}
-
-void ProceduralSky::set_ground_curve(float p_curve) {
-
- ground_curve = p_curve;
- _queue_update();
-}
-float ProceduralSky::get_ground_curve() const {
-
- return ground_curve;
-}
-
-void ProceduralSky::set_ground_energy(float p_energy) {
-
- ground_energy = p_energy;
- _queue_update();
-}
-float ProceduralSky::get_ground_energy() const {
-
- return ground_energy;
-}
-
-void ProceduralSky::set_sun_color(const Color &p_sun) {
-
- sun_color = p_sun;
- _queue_update();
-}
-Color ProceduralSky::get_sun_color() const {
-
- return sun_color;
-}
-
-void ProceduralSky::set_sun_latitude(float p_angle) {
-
- sun_latitude = p_angle;
- _queue_update();
-}
-float ProceduralSky::get_sun_latitude() const {
-
- return sun_latitude;
-}
-
-void ProceduralSky::set_sun_longitude(float p_angle) {
-
- sun_longitude = p_angle;
- _queue_update();
-}
-float ProceduralSky::get_sun_longitude() const {
-
- return sun_longitude;
-}
-
-void ProceduralSky::set_sun_angle_min(float p_angle) {
-
- sun_angle_min = p_angle;
- _queue_update();
-}
-float ProceduralSky::get_sun_angle_min() const {
-
- return sun_angle_min;
-}
-
-void ProceduralSky::set_sun_angle_max(float p_angle) {
-
- sun_angle_max = p_angle;
- _queue_update();
-}
-float ProceduralSky::get_sun_angle_max() const {
-
- return sun_angle_max;
-}
-
-void ProceduralSky::set_sun_curve(float p_curve) {
-
- sun_curve = p_curve;
- _queue_update();
-}
-float ProceduralSky::get_sun_curve() const {
-
- return sun_curve;
-}
-
-void ProceduralSky::set_sun_energy(float p_energy) {
-
- sun_energy = p_energy;
- _queue_update();
+Sky::RadianceSize Sky::get_radiance_size() const {
+ return radiance_size;
}
-float ProceduralSky::get_sun_energy() const {
- return sun_energy;
+void Sky::set_process_mode(ProcessMode p_mode) {
+ mode = p_mode;
+ RS::get_singleton()->sky_set_mode(sky, RS::SkyMode(mode));
}
-void ProceduralSky::set_texture_size(TextureSize p_size) {
- ERR_FAIL_INDEX(p_size, TEXTURE_SIZE_MAX);
-
- texture_size = p_size;
- _queue_update();
-}
-ProceduralSky::TextureSize ProceduralSky::get_texture_size() const {
- return texture_size;
+Sky::ProcessMode Sky::get_process_mode() const {
+ return mode;
}
-RID ProceduralSky::get_rid() const {
- return sky;
-}
-
-void ProceduralSky::_update_sky() {
-
- bool use_thread = true;
- if (first_time) {
- use_thread = false;
- first_time = false;
- }
-#ifdef NO_THREADS
- use_thread = false;
-#endif
- if (use_thread) {
-
- if (!sky_thread) {
- sky_thread = Thread::create(_thread_function, this);
- regen_queued = false;
- } else {
- regen_queued = true;
- }
-
- } else {
- Ref<Image> image = _generate_sky();
- VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
- VS::get_singleton()->texture_set_data(texture, image);
- _radiance_changed();
+void Sky::set_material(const Ref<Material> &p_material) {
+ sky_material = p_material;
+ RID material_rid;
+ if (sky_material.is_valid()) {
+ material_rid = sky_material->get_rid();
}
+ RS::get_singleton()->sky_set_material(sky, material_rid);
}
-void ProceduralSky::_queue_update() {
-
- if (update_queued)
- return;
-
- update_queued = true;
- call_deferred("_update_sky");
+Ref<Material> Sky::get_material() const {
+ return sky_material;
}
-void ProceduralSky::_thread_done(const Ref<Image> &p_image) {
-
- VS::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
- VS::get_singleton()->texture_set_data(texture, p_image);
- _radiance_changed();
- Thread::wait_to_finish(sky_thread);
- memdelete(sky_thread);
- sky_thread = NULL;
- if (regen_queued) {
- sky_thread = Thread::create(_thread_function, this);
- regen_queued = false;
- }
-}
-
-void ProceduralSky::_thread_function(void *p_ud) {
-
- ProceduralSky *psky = (ProceduralSky *)p_ud;
- psky->call_deferred("_thread_done", psky->_generate_sky());
+RID Sky::get_rid() const {
+ return sky;
}
-void ProceduralSky::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("_update_sky"), &ProceduralSky::_update_sky);
-
- ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSky::set_sky_top_color);
- ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSky::get_sky_top_color);
-
- ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSky::set_sky_horizon_color);
- ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSky::get_sky_horizon_color);
-
- ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSky::set_sky_curve);
- ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSky::get_sky_curve);
-
- ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSky::set_sky_energy);
- ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSky::get_sky_energy);
-
- ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSky::set_ground_bottom_color);
- ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSky::get_ground_bottom_color);
-
- ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSky::set_ground_horizon_color);
- ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSky::get_ground_horizon_color);
-
- ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSky::set_ground_curve);
- ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSky::get_ground_curve);
-
- ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSky::set_ground_energy);
- ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSky::get_ground_energy);
-
- ClassDB::bind_method(D_METHOD("set_sun_color", "color"), &ProceduralSky::set_sun_color);
- ClassDB::bind_method(D_METHOD("get_sun_color"), &ProceduralSky::get_sun_color);
-
- ClassDB::bind_method(D_METHOD("set_sun_latitude", "degrees"), &ProceduralSky::set_sun_latitude);
- ClassDB::bind_method(D_METHOD("get_sun_latitude"), &ProceduralSky::get_sun_latitude);
-
- ClassDB::bind_method(D_METHOD("set_sun_longitude", "degrees"), &ProceduralSky::set_sun_longitude);
- ClassDB::bind_method(D_METHOD("get_sun_longitude"), &ProceduralSky::get_sun_longitude);
-
- ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSky::set_sun_angle_min);
- ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSky::get_sun_angle_min);
-
- ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSky::set_sun_angle_max);
- ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSky::get_sun_angle_max);
-
- ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSky::set_sun_curve);
- ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSky::get_sun_curve);
-
- ClassDB::bind_method(D_METHOD("set_sun_energy", "energy"), &ProceduralSky::set_sun_energy);
- ClassDB::bind_method(D_METHOD("get_sun_energy"), &ProceduralSky::get_sun_energy);
-
- ClassDB::bind_method(D_METHOD("set_texture_size", "size"), &ProceduralSky::set_texture_size);
- ClassDB::bind_method(D_METHOD("get_texture_size"), &ProceduralSky::get_texture_size);
-
- ClassDB::bind_method(D_METHOD("_thread_done", "image"), &ProceduralSky::_thread_done);
+void Sky::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size);
+ ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size);
- ADD_GROUP("Sky", "sky_");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
+ ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Sky::set_process_mode);
+ ClassDB::bind_method(D_METHOD("get_process_mode"), &Sky::get_process_mode);
- ADD_GROUP("Ground", "ground_");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &Sky::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &Sky::get_material);
- ADD_GROUP("Sun", "sun_");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sun_color"), "set_sun_color", "get_sun_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,PanoramaSkyMaterial,ProceduralSkyMaterial,PhysicalSkyMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Automatic,HighQuality,HighQualityIncremental,RealTime"), "set_process_mode", "get_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size");
- ADD_GROUP("Texture", "texture_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_texture_size", "get_texture_size");
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_32);
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_64);
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_128);
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_256);
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_512);
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024);
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048);
+ BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX);
- BIND_ENUM_CONSTANT(TEXTURE_SIZE_256);
- BIND_ENUM_CONSTANT(TEXTURE_SIZE_512);
- BIND_ENUM_CONSTANT(TEXTURE_SIZE_1024);
- BIND_ENUM_CONSTANT(TEXTURE_SIZE_2048);
- BIND_ENUM_CONSTANT(TEXTURE_SIZE_4096);
- BIND_ENUM_CONSTANT(TEXTURE_SIZE_MAX);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_AUTOMATIC);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_QUALITY);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_INCREMENTAL);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_REALTIME);
}
-ProceduralSky::ProceduralSky(bool p_desaturate) {
-
- sky = VS::get_singleton()->sky_create();
- texture = VS::get_singleton()->texture_create();
-
- update_queued = false;
- sky_top_color = Color::hex(0xa5d6f1ff);
- sky_horizon_color = Color::hex(0xd6eafaff);
- sky_curve = 0.09;
- sky_energy = 1;
-
- ground_bottom_color = Color::hex(0x282f36ff);
- ground_horizon_color = Color::hex(0x6c655fff);
- ground_curve = 0.02;
- ground_energy = 1;
-
- if (p_desaturate) {
- sky_top_color.set_hsv(sky_top_color.get_h(), 0, sky_top_color.get_v());
- sky_horizon_color.set_hsv(sky_horizon_color.get_h(), 0, sky_horizon_color.get_v());
- ground_bottom_color.set_hsv(ground_bottom_color.get_h(), 0, ground_bottom_color.get_v());
- ground_horizon_color.set_hsv(ground_horizon_color.get_h(), 0, ground_horizon_color.get_v());
- }
- sun_color = Color(1, 1, 1);
- sun_latitude = 35;
- sun_longitude = 0;
- sun_angle_min = 1;
- sun_angle_max = 100;
- sun_curve = 0.05;
- sun_energy = 1;
-
- texture_size = TEXTURE_SIZE_1024;
- sky_thread = NULL;
- regen_queued = false;
- first_time = true;
-
- _queue_update();
+Sky::Sky() {
+ mode = PROCESS_MODE_AUTOMATIC;
+ radiance_size = RADIANCE_SIZE_256;
+ sky = RS::get_singleton()->sky_create();
}
-ProceduralSky::~ProceduralSky() {
-
- if (sky_thread) {
- Thread::wait_to_finish(sky_thread);
- memdelete(sky_thread);
- sky_thread = NULL;
- }
- VS::get_singleton()->free(sky);
- VS::get_singleton()->free(texture);
+Sky::~Sky() {
+ RS::get_singleton()->free(sky);
}
diff --git a/scene/resources/sky.h b/scene/resources/sky.h
index 70ea9c4c18..526ca94317 100644
--- a/scene/resources/sky.h
+++ b/scene/resources/sky.h
@@ -32,6 +32,7 @@
#define SKY_H
#include "core/os/thread.h"
+#include "scene/resources/material.h"
#include "scene/resources/texture.h"
class Sky : public Resource {
@@ -49,152 +50,39 @@ public:
RADIANCE_SIZE_MAX
};
-private:
- RadianceSize radiance_size;
-
-protected:
- static void _bind_methods();
- virtual void _radiance_changed() = 0;
-
-public:
- void set_radiance_size(RadianceSize p_size);
- RadianceSize get_radiance_size() const;
- Sky();
-};
-
-VARIANT_ENUM_CAST(Sky::RadianceSize)
-
-class PanoramaSky : public Sky {
- GDCLASS(PanoramaSky, Sky);
-
-private:
- RID sky;
- Ref<Texture> panorama;
-
-protected:
- static void _bind_methods();
- virtual void _radiance_changed();
-
-public:
- void set_panorama(const Ref<Texture> &p_panorama);
- Ref<Texture> get_panorama() const;
-
- virtual RID get_rid() const;
-
- PanoramaSky();
- ~PanoramaSky();
-};
-
-class ProceduralSky : public Sky {
- GDCLASS(ProceduralSky, Sky);
-
-public:
- enum TextureSize {
- TEXTURE_SIZE_256,
- TEXTURE_SIZE_512,
- TEXTURE_SIZE_1024,
- TEXTURE_SIZE_2048,
- TEXTURE_SIZE_4096,
- TEXTURE_SIZE_MAX
+ enum ProcessMode {
+ PROCESS_MODE_AUTOMATIC,
+ PROCESS_MODE_QUALITY,
+ PROCESS_MODE_INCREMENTAL,
+ PROCESS_MODE_REALTIME
};
private:
- Thread *sky_thread;
- Color sky_top_color;
- Color sky_horizon_color;
- float sky_curve;
- float sky_energy;
-
- Color ground_bottom_color;
- Color ground_horizon_color;
- float ground_curve;
- float ground_energy;
-
- Color sun_color;
- float sun_latitude;
- float sun_longitude;
- float sun_angle_min;
- float sun_angle_max;
- float sun_curve;
- float sun_energy;
-
- TextureSize texture_size;
-
RID sky;
- RID texture;
-
- bool update_queued;
- bool regen_queued;
-
- bool first_time;
-
- void _thread_done(const Ref<Image> &p_image);
- static void _thread_function(void *p_ud);
+ ProcessMode mode;
+ RadianceSize radiance_size;
+ Ref<Material> sky_material;
protected:
static void _bind_methods();
- virtual void _radiance_changed();
-
- Ref<Image> _generate_sky();
- void _update_sky();
-
- void _queue_update();
public:
- void set_sky_top_color(const Color &p_sky_top);
- Color get_sky_top_color() const;
-
- void set_sky_horizon_color(const Color &p_sky_horizon);
- Color get_sky_horizon_color() const;
-
- void set_sky_curve(float p_curve);
- float get_sky_curve() const;
-
- void set_sky_energy(float p_energy);
- float get_sky_energy() const;
-
- void set_ground_bottom_color(const Color &p_ground_bottom);
- Color get_ground_bottom_color() const;
-
- void set_ground_horizon_color(const Color &p_ground_horizon);
- Color get_ground_horizon_color() const;
-
- void set_ground_curve(float p_curve);
- float get_ground_curve() const;
-
- void set_ground_energy(float p_energy);
- float get_ground_energy() const;
-
- void set_sun_color(const Color &p_sun);
- Color get_sun_color() const;
-
- void set_sun_latitude(float p_angle);
- float get_sun_latitude() const;
-
- void set_sun_longitude(float p_angle);
- float get_sun_longitude() const;
-
- void set_sun_angle_min(float p_angle);
- float get_sun_angle_min() const;
-
- void set_sun_angle_max(float p_angle);
- float get_sun_angle_max() const;
-
- void set_sun_curve(float p_curve);
- float get_sun_curve() const;
+ void set_radiance_size(RadianceSize p_size);
+ RadianceSize get_radiance_size() const;
- void set_sun_energy(float p_energy);
- float get_sun_energy() const;
+ void set_process_mode(ProcessMode p_mode);
+ ProcessMode get_process_mode() const;
- void set_texture_size(TextureSize p_size);
- TextureSize get_texture_size() const;
+ void set_material(const Ref<Material> &p_material);
+ Ref<Material> get_material() const;
- virtual RID get_rid() const;
+ virtual RID get_rid() const override;
- ProceduralSky(bool p_desaturate = false);
- ~ProceduralSky();
+ Sky();
+ ~Sky();
};
-VARIANT_ENUM_CAST(ProceduralSky::TextureSize)
+VARIANT_ENUM_CAST(Sky::RadianceSize)
+VARIANT_ENUM_CAST(Sky::ProcessMode)
#endif // SKY_H
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
new file mode 100644
index 0000000000..69e8e0b5bd
--- /dev/null
+++ b/scene/resources/sky_material.cpp
@@ -0,0 +1,595 @@
+/*************************************************************************/
+/* sky_material.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "sky_material.h"
+
+void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) {
+ sky_top_color = p_sky_top;
+ RS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color.to_linear());
+}
+
+Color ProceduralSkyMaterial::get_sky_top_color() const {
+ return sky_top_color;
+}
+
+void ProceduralSkyMaterial::set_sky_horizon_color(const Color &p_sky_horizon) {
+ sky_horizon_color = p_sky_horizon;
+ RS::get_singleton()->material_set_param(_get_material(), "sky_horizon_color", sky_horizon_color.to_linear());
+}
+
+Color ProceduralSkyMaterial::get_sky_horizon_color() const {
+ return sky_horizon_color;
+}
+
+void ProceduralSkyMaterial::set_sky_curve(float p_curve) {
+ sky_curve = p_curve;
+ RS::get_singleton()->material_set_param(_get_material(), "sky_curve", sky_curve);
+}
+
+float ProceduralSkyMaterial::get_sky_curve() const {
+ return sky_curve;
+}
+
+void ProceduralSkyMaterial::set_sky_energy(float p_energy) {
+ sky_energy = p_energy;
+ RS::get_singleton()->material_set_param(_get_material(), "sky_energy", sky_energy);
+}
+
+float ProceduralSkyMaterial::get_sky_energy() const {
+ return sky_energy;
+}
+
+void ProceduralSkyMaterial::set_ground_bottom_color(const Color &p_ground_bottom) {
+ ground_bottom_color = p_ground_bottom;
+ RS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color.to_linear());
+}
+
+Color ProceduralSkyMaterial::get_ground_bottom_color() const {
+ return ground_bottom_color;
+}
+
+void ProceduralSkyMaterial::set_ground_horizon_color(const Color &p_ground_horizon) {
+ ground_horizon_color = p_ground_horizon;
+ RS::get_singleton()->material_set_param(_get_material(), "ground_horizon_color", ground_horizon_color.to_linear());
+}
+
+Color ProceduralSkyMaterial::get_ground_horizon_color() const {
+ return ground_horizon_color;
+}
+
+void ProceduralSkyMaterial::set_ground_curve(float p_curve) {
+ ground_curve = p_curve;
+ RS::get_singleton()->material_set_param(_get_material(), "ground_curve", ground_curve);
+}
+
+float ProceduralSkyMaterial::get_ground_curve() const {
+ return ground_curve;
+}
+
+void ProceduralSkyMaterial::set_ground_energy(float p_energy) {
+ ground_energy = p_energy;
+ RS::get_singleton()->material_set_param(_get_material(), "ground_energy", ground_energy);
+}
+
+float ProceduralSkyMaterial::get_ground_energy() const {
+ return ground_energy;
+}
+
+void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) {
+ sun_angle_max = p_angle;
+ RS::get_singleton()->material_set_param(_get_material(), "sun_angle_max", Math::deg2rad(sun_angle_max));
+}
+
+float ProceduralSkyMaterial::get_sun_angle_max() const {
+ return sun_angle_max;
+}
+
+void ProceduralSkyMaterial::set_sun_curve(float p_curve) {
+ sun_curve = p_curve;
+ RS::get_singleton()->material_set_param(_get_material(), "sun_curve", sun_curve);
+}
+
+float ProceduralSkyMaterial::get_sun_curve() const {
+ return sun_curve;
+}
+
+bool ProceduralSkyMaterial::_can_do_next_pass() const {
+ return false;
+}
+
+Shader::Mode ProceduralSkyMaterial::get_shader_mode() const {
+ return Shader::MODE_SKY;
+}
+
+RID ProceduralSkyMaterial::get_shader_rid() const {
+ return shader;
+}
+
+void ProceduralSkyMaterial::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSkyMaterial::set_sky_top_color);
+ ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSkyMaterial::get_sky_top_color);
+
+ ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSkyMaterial::set_sky_horizon_color);
+ ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSkyMaterial::get_sky_horizon_color);
+
+ ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSkyMaterial::set_sky_curve);
+ ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSkyMaterial::get_sky_curve);
+
+ ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSkyMaterial::set_sky_energy);
+ ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSkyMaterial::get_sky_energy);
+
+ ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSkyMaterial::set_ground_bottom_color);
+ ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSkyMaterial::get_ground_bottom_color);
+
+ ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSkyMaterial::set_ground_horizon_color);
+ ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSkyMaterial::get_ground_horizon_color);
+
+ ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSkyMaterial::set_ground_curve);
+ ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSkyMaterial::get_ground_curve);
+
+ ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSkyMaterial::set_ground_energy);
+ ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSkyMaterial::get_ground_energy);
+
+ ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSkyMaterial::set_sun_angle_max);
+ ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSkyMaterial::get_sun_angle_max);
+
+ ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSkyMaterial::set_sun_curve);
+ ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSkyMaterial::get_sun_curve);
+
+ ADD_GROUP("Sky", "sky_");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
+
+ ADD_GROUP("Ground", "ground_");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
+
+ ADD_GROUP("Sun", "sun_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
+}
+
+ProceduralSkyMaterial::ProceduralSkyMaterial() {
+ String code = "shader_type sky;\n\n";
+
+ code += "uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);\n";
+ code += "uniform vec4 sky_horizon_color : hint_color = vec4(0.55, 0.69, 0.81, 1.0);\n";
+ code += "uniform float sky_curve : hint_range(0, 1) = 0.09;\n";
+ code += "uniform float sky_energy = 1.0;\n\n";
+ code += "uniform vec4 ground_bottom_color : hint_color = vec4(0.12, 0.12, 0.13, 1.0);\n";
+ code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n";
+ code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n";
+ code += "uniform float ground_energy = 1.0;\n\n";
+ code += "uniform float sun_angle_max = 1.74;\n";
+ code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n";
+ code += "const float PI = 3.1415926535897932384626433833;\n\n";
+ code += "void fragment() {\n";
+ code += "\tfloat v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));\n";
+ code += "\tfloat c = (1.0 - v_angle / (PI * 0.5));\n";
+ code += "\tvec3 sky = mix(sky_horizon_color.rgb, sky_top_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / sky_curve), 0.0, 1.0));\n";
+ code += "\tsky *= sky_energy;\n";
+ code += "\tif (LIGHT0_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < LIGHT0_SIZE) {\n";
+ code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT0_SIZE) / (sun_angle_max - LIGHT0_SIZE);\n";
+ code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tif (LIGHT1_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < LIGHT1_SIZE) {\n";
+ code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT1_SIZE) / (sun_angle_max - LIGHT1_SIZE);\n";
+ code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tif (LIGHT2_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < LIGHT2_SIZE) {\n";
+ code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT2_SIZE) / (sun_angle_max - LIGHT2_SIZE);\n";
+ code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tif (LIGHT3_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < LIGHT3_SIZE) {\n";
+ code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT3_SIZE) / (sun_angle_max - LIGHT3_SIZE);\n";
+ code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tc = (v_angle - (PI * 0.5)) / (PI * 0.5);\n";
+ code += "\tvec3 ground = mix(ground_horizon_color.rgb, ground_bottom_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / ground_curve), 0.0, 1.0));\n";
+ code += "\tground *= ground_energy;\n";
+ code += "\tCOLOR = mix(ground, sky, step(0.0, EYEDIR.y));\n";
+ code += "}\n";
+
+ shader = RS::get_singleton()->shader_create();
+
+ RS::get_singleton()->shader_set_code(shader, code);
+
+ RS::get_singleton()->material_set_shader(_get_material(), shader);
+
+ set_sky_top_color(Color(0.35, 0.46, 0.71));
+ set_sky_horizon_color(Color(0.55, 0.69, 0.81));
+ set_sky_curve(0.09);
+ set_sky_energy(1.0);
+
+ set_ground_bottom_color(Color(0.12, 0.12, 0.13));
+ set_ground_horizon_color(Color(0.37, 0.33, 0.31));
+ set_ground_curve(0.02);
+ set_ground_energy(1.0);
+
+ set_sun_angle_max(100.0);
+ set_sun_curve(0.05);
+}
+
+ProceduralSkyMaterial::~ProceduralSkyMaterial() {
+ RS::get_singleton()->free(shader);
+ RS::get_singleton()->material_set_shader(_get_material(), RID());
+}
+
+/////////////////////////////////////////
+/* PanoramaSkyMaterial */
+
+void PanoramaSkyMaterial::set_panorama(const Ref<Texture2D> &p_panorama) {
+ panorama = p_panorama;
+ RS::get_singleton()->material_set_param(_get_material(), "source_panorama", panorama);
+}
+
+Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
+ return panorama;
+}
+
+bool PanoramaSkyMaterial::_can_do_next_pass() const {
+ return false;
+}
+
+Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
+ return Shader::MODE_SKY;
+}
+
+RID PanoramaSkyMaterial::get_shader_rid() const {
+ return shader;
+}
+
+void PanoramaSkyMaterial::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama);
+ ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
+}
+
+PanoramaSkyMaterial::PanoramaSkyMaterial() {
+ String code = "shader_type sky;\n\n";
+
+ code += "uniform sampler2D source_panorama : filter_linear;\n";
+ code += "void fragment() {\n";
+ code += "\tCOLOR = texture(source_panorama, SKY_COORDS).rgb;\n";
+ code += "}";
+
+ shader = RS::get_singleton()->shader_create();
+
+ RS::get_singleton()->shader_set_code(shader, code);
+
+ RS::get_singleton()->material_set_shader(_get_material(), shader);
+}
+
+PanoramaSkyMaterial::~PanoramaSkyMaterial() {
+ RS::get_singleton()->free(shader);
+ RS::get_singleton()->material_set_shader(_get_material(), RID());
+}
+
+//////////////////////////////////
+/* PhysicalSkyMaterial */
+
+void PhysicalSkyMaterial::set_rayleigh_coefficient(float p_rayleigh) {
+ rayleigh = p_rayleigh;
+ RS::get_singleton()->material_set_param(_get_material(), "rayleigh", rayleigh);
+}
+
+float PhysicalSkyMaterial::get_rayleigh_coefficient() const {
+ return rayleigh;
+}
+
+void PhysicalSkyMaterial::set_rayleigh_color(Color p_rayleigh_color) {
+ rayleigh_color = p_rayleigh_color;
+ RS::get_singleton()->material_set_param(_get_material(), "rayleigh_color", rayleigh_color);
+}
+
+Color PhysicalSkyMaterial::get_rayleigh_color() const {
+ return rayleigh_color;
+}
+
+void PhysicalSkyMaterial::set_mie_coefficient(float p_mie) {
+ mie = p_mie;
+ RS::get_singleton()->material_set_param(_get_material(), "mie", mie);
+}
+
+float PhysicalSkyMaterial::get_mie_coefficient() const {
+ return mie;
+}
+
+void PhysicalSkyMaterial::set_mie_eccentricity(float p_eccentricity) {
+ mie_eccentricity = p_eccentricity;
+ RS::get_singleton()->material_set_param(_get_material(), "mie_eccentricity", mie_eccentricity);
+}
+
+float PhysicalSkyMaterial::get_mie_eccentricity() const {
+ return mie_eccentricity;
+}
+
+void PhysicalSkyMaterial::set_mie_color(Color p_mie_color) {
+ mie_color = p_mie_color;
+ RS::get_singleton()->material_set_param(_get_material(), "mie_color", mie_color);
+}
+
+Color PhysicalSkyMaterial::get_mie_color() const {
+ return mie_color;
+}
+
+void PhysicalSkyMaterial::set_turbidity(float p_turbidity) {
+ turbidity = p_turbidity;
+ RS::get_singleton()->material_set_param(_get_material(), "turbidity", turbidity);
+}
+
+float PhysicalSkyMaterial::get_turbidity() const {
+ return turbidity;
+}
+
+void PhysicalSkyMaterial::set_sun_disk_scale(float p_sun_disk_scale) {
+ sun_disk_scale = p_sun_disk_scale;
+ RS::get_singleton()->material_set_param(_get_material(), "sun_disk_scale", sun_disk_scale);
+}
+
+float PhysicalSkyMaterial::get_sun_disk_scale() const {
+ return sun_disk_scale;
+}
+
+void PhysicalSkyMaterial::set_ground_color(Color p_ground_color) {
+ ground_color = p_ground_color;
+ RS::get_singleton()->material_set_param(_get_material(), "ground_color", ground_color);
+}
+
+Color PhysicalSkyMaterial::get_ground_color() const {
+ return ground_color;
+}
+
+void PhysicalSkyMaterial::set_exposure(float p_exposure) {
+ exposure = p_exposure;
+ RS::get_singleton()->material_set_param(_get_material(), "exposure", exposure);
+}
+
+float PhysicalSkyMaterial::get_exposure() const {
+ return exposure;
+}
+
+void PhysicalSkyMaterial::set_dither_strength(float p_dither_strength) {
+ dither_strength = p_dither_strength;
+ RS::get_singleton()->material_set_param(_get_material(), "dither_strength", dither_strength);
+}
+
+float PhysicalSkyMaterial::get_dither_strength() const {
+ return dither_strength;
+}
+
+void PhysicalSkyMaterial::set_night_sky(const Ref<Texture2D> &p_night_sky) {
+ night_sky = p_night_sky;
+ RS::get_singleton()->material_set_param(_get_material(), "night_sky", night_sky);
+}
+
+Ref<Texture2D> PhysicalSkyMaterial::get_night_sky() const {
+ return night_sky;
+}
+
+bool PhysicalSkyMaterial::_can_do_next_pass() const {
+ return false;
+}
+
+Shader::Mode PhysicalSkyMaterial::get_shader_mode() const {
+ return Shader::MODE_SKY;
+}
+
+RID PhysicalSkyMaterial::get_shader_rid() const {
+ return shader;
+}
+
+void PhysicalSkyMaterial::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_rayleigh_coefficient", "rayleigh"), &PhysicalSkyMaterial::set_rayleigh_coefficient);
+ ClassDB::bind_method(D_METHOD("get_rayleigh_coefficient"), &PhysicalSkyMaterial::get_rayleigh_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_rayleigh_color", "color"), &PhysicalSkyMaterial::set_rayleigh_color);
+ ClassDB::bind_method(D_METHOD("get_rayleigh_color"), &PhysicalSkyMaterial::get_rayleigh_color);
+
+ ClassDB::bind_method(D_METHOD("set_mie_coefficient", "mie"), &PhysicalSkyMaterial::set_mie_coefficient);
+ ClassDB::bind_method(D_METHOD("get_mie_coefficient"), &PhysicalSkyMaterial::get_mie_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_mie_eccentricity", "eccentricity"), &PhysicalSkyMaterial::set_mie_eccentricity);
+ ClassDB::bind_method(D_METHOD("get_mie_eccentricity"), &PhysicalSkyMaterial::get_mie_eccentricity);
+
+ ClassDB::bind_method(D_METHOD("set_mie_color", "color"), &PhysicalSkyMaterial::set_mie_color);
+ ClassDB::bind_method(D_METHOD("get_mie_color"), &PhysicalSkyMaterial::get_mie_color);
+
+ ClassDB::bind_method(D_METHOD("set_turbidity", "turbidity"), &PhysicalSkyMaterial::set_turbidity);
+ ClassDB::bind_method(D_METHOD("get_turbidity"), &PhysicalSkyMaterial::get_turbidity);
+
+ ClassDB::bind_method(D_METHOD("set_sun_disk_scale", "scale"), &PhysicalSkyMaterial::set_sun_disk_scale);
+ ClassDB::bind_method(D_METHOD("get_sun_disk_scale"), &PhysicalSkyMaterial::get_sun_disk_scale);
+
+ ClassDB::bind_method(D_METHOD("set_ground_color", "color"), &PhysicalSkyMaterial::set_ground_color);
+ ClassDB::bind_method(D_METHOD("get_ground_color"), &PhysicalSkyMaterial::get_ground_color);
+
+ ClassDB::bind_method(D_METHOD("set_exposure", "exposure"), &PhysicalSkyMaterial::set_exposure);
+ ClassDB::bind_method(D_METHOD("get_exposure"), &PhysicalSkyMaterial::get_exposure);
+
+ ClassDB::bind_method(D_METHOD("set_dither_strength", "strength"), &PhysicalSkyMaterial::set_dither_strength);
+ ClassDB::bind_method(D_METHOD("get_dither_strength"), &PhysicalSkyMaterial::get_dither_strength);
+
+ ClassDB::bind_method(D_METHOD("set_night_sky", "night_sky"), &PhysicalSkyMaterial::set_night_sky);
+ ClassDB::bind_method(D_METHOD("get_night_sky"), &PhysicalSkyMaterial::get_night_sky);
+
+ ADD_GROUP("Rayleigh", "rayleigh_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rayleigh_coefficient", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_rayleigh_coefficient", "get_rayleigh_coefficient");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "rayleigh_color"), "set_rayleigh_color", "get_rayleigh_color");
+
+ ADD_GROUP("Mie", "mie_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mie_coefficient", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_mie_coefficient", "get_mie_coefficient");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mie_eccentricity", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_mie_eccentricity", "get_mie_eccentricity");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "mie_color"), "set_mie_color", "get_mie_color");
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbidity", PROPERTY_HINT_RANGE, "0,1000,0.01"), "set_turbidity", "get_turbidity");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_disk_scale", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_disk_scale", "get_sun_disk_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_color"), "set_ground_color", "get_ground_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "exposure", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_exposure", "get_exposure");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dither_strength", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_dither_strength", "get_dither_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "night_sky", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_night_sky", "get_night_sky");
+}
+
+PhysicalSkyMaterial::PhysicalSkyMaterial() {
+ String code = "shader_type sky;\n\n";
+
+ code += "uniform float rayleigh : hint_range(0, 64) = 2.0;\n";
+ code += "uniform vec4 rayleigh_color : hint_color = vec4(0.056, 0.14, 0.3, 1.0);\n";
+ code += "uniform float mie : hint_range(0, 1) = 0.005;\n";
+ code += "uniform float mie_eccentricity : hint_range(-1, 1) = 0.8;\n";
+ code += "uniform vec4 mie_color : hint_color = vec4(0.36, 0.56, 0.82, 1.0);\n\n";
+
+ code += "uniform float turbidity : hint_range(0, 1000) = 10.0;\n";
+ code += "uniform float sun_disk_scale : hint_range(0, 360) = 1.0;\n";
+ code += "uniform vec4 ground_color : hint_color = vec4(1.0);\n";
+ code += "uniform float exposure : hint_range(0, 128) = 0.1;\n";
+ code += "uniform float dither_strength : hint_range(0, 10) = 1.0;\n\n";
+
+ code += "uniform sampler2D night_sky : hint_black;";
+
+ code += "const float PI = 3.141592653589793238462643383279502884197169;\n";
+ code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n";
+
+ code += "// Sun constants\n";
+ code += "const float SUN_ENERGY = 1000.0;\n\n";
+
+ code += "// optical length at zenith for molecules\n";
+ code += "const float rayleigh_zenith_size = 8.4e3;\n";
+ code += "const float mie_zenith_size = 1.25e3;\n\n";
+
+ code += "float henyey_greenstein(float cos_theta, float g) {\n";
+ code += "\tconst float k = 0.0795774715459;\n";
+ code += "\treturn k * (1.0 - g * g) / (pow(1.0 + g * g - 2.0 * g * cos_theta, 1.5));\n";
+ code += "}\n\n";
+
+ code += "// From: https://www.shadertoy.com/view/4sfGzS credit to iq\n";
+ code += "float hash(vec3 p) {\n";
+ code += "\tp = fract( p * 0.3183099 + 0.1 );\n";
+ code += "\tp *= 17.0;\n";
+ code += "\treturn fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n";
+ code += "}\n\n";
+
+ code += "void fragment() {\n";
+ code += "\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
+ code += "\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
+ code += "\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
+
+ code += "\t// rayleigh coefficients\n";
+ code += "\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
+ code += "\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
+ code += "\t// mie coefficients from Preetham\n";
+ code += "\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
+
+ code += "\t// optical length\n";
+ code += "\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
+ code += "\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
+ code += "\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
+ code += "\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
+
+ code += "\t// light extinction based on thickness of atmosphere\n";
+ code += "\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
+
+ code += "\t// in scattering\n";
+ code += "\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
+
+ code += "\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
+ code += "\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
+
+ code += "\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
+ code += "\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
+
+ code += "\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
+ code += "\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
+ code += "\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
+
+ code += "\t// Hack in the ground color\n";
+ code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
+
+ code += "\t// Solar disk and out-scattering\n";
+ code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
+ code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
+ code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
+ code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
+ code += "\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n";
+
+ code += "\tvec3 color = (Lin + L0) * 0.04;\n";
+ code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
+ code += "\tCOLOR *= exposure;\n";
+ code += "\t// Make optional, eliminates banding\n";
+ code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.008 * dither_strength;\n";
+ code += "}\n";
+
+ shader = RS::get_singleton()->shader_create();
+
+ RS::get_singleton()->shader_set_code(shader, code);
+
+ RS::get_singleton()->material_set_shader(_get_material(), shader);
+
+ set_rayleigh_coefficient(2.0);
+ set_rayleigh_color(Color(0.056, 0.14, 0.3));
+ set_mie_coefficient(0.005);
+ set_mie_eccentricity(0.8);
+ set_mie_color(Color(0.36, 0.56, 0.82));
+ set_turbidity(10.0);
+ set_sun_disk_scale(1.0);
+ set_ground_color(Color(1.0, 1.0, 1.0));
+ set_exposure(0.1);
+ set_dither_strength(1.0);
+}
+
+PhysicalSkyMaterial::~PhysicalSkyMaterial() {
+ RS::get_singleton()->free(shader);
+ RS::get_singleton()->material_set_shader(_get_material(), RID());
+}
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
new file mode 100644
index 0000000000..5e23020d66
--- /dev/null
+++ b/scene/resources/sky_material.h
@@ -0,0 +1,189 @@
+/*************************************************************************/
+/* sky_material.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "core/rid.h"
+#include "scene/resources/material.h"
+
+#ifndef SKY_MATERIAL_H
+#define SKY_MATERIAL_H
+
+class ProceduralSkyMaterial : public Material {
+ GDCLASS(ProceduralSkyMaterial, Material);
+
+private:
+ Color sky_top_color;
+ Color sky_horizon_color;
+ float sky_curve;
+ float sky_energy;
+
+ Color ground_bottom_color;
+ Color ground_horizon_color;
+ float ground_curve;
+ float ground_energy;
+
+ float sun_angle_max;
+ float sun_curve;
+
+ RID shader;
+
+protected:
+ static void _bind_methods();
+ virtual bool _can_do_next_pass() const override;
+
+public:
+ void set_sky_top_color(const Color &p_sky_top);
+ Color get_sky_top_color() const;
+
+ void set_sky_horizon_color(const Color &p_sky_horizon);
+ Color get_sky_horizon_color() const;
+
+ void set_sky_curve(float p_curve);
+ float get_sky_curve() const;
+
+ void set_sky_energy(float p_energy);
+ float get_sky_energy() const;
+
+ void set_ground_bottom_color(const Color &p_ground_bottom);
+ Color get_ground_bottom_color() const;
+
+ void set_ground_horizon_color(const Color &p_ground_horizon);
+ Color get_ground_horizon_color() const;
+
+ void set_ground_curve(float p_curve);
+ float get_ground_curve() const;
+
+ void set_ground_energy(float p_energy);
+ float get_ground_energy() const;
+
+ void set_sun_angle_max(float p_angle);
+ float get_sun_angle_max() const;
+
+ void set_sun_curve(float p_curve);
+ float get_sun_curve() const;
+
+ virtual Shader::Mode get_shader_mode() const override;
+ RID get_shader_rid() const;
+
+ ProceduralSkyMaterial();
+ ~ProceduralSkyMaterial();
+};
+
+//////////////////////////////////////////////////////
+/* PanoramaSkyMaterial */
+
+class PanoramaSkyMaterial : public Material {
+ GDCLASS(PanoramaSkyMaterial, Material);
+
+private:
+ Ref<Texture2D> panorama;
+ RID shader;
+
+protected:
+ static void _bind_methods();
+ virtual bool _can_do_next_pass() const override;
+
+public:
+ void set_panorama(const Ref<Texture2D> &p_panorama);
+ Ref<Texture2D> get_panorama() const;
+
+ virtual Shader::Mode get_shader_mode() const override;
+ RID get_shader_rid() const;
+
+ PanoramaSkyMaterial();
+ ~PanoramaSkyMaterial();
+};
+
+//////////////////////////////////////////////////////
+/* PanoramaSkyMaterial */
+
+class PhysicalSkyMaterial : public Material {
+ GDCLASS(PhysicalSkyMaterial, Material);
+
+private:
+ RID shader;
+
+ float rayleigh;
+ Color rayleigh_color;
+ float mie;
+ float mie_eccentricity;
+ Color mie_color;
+ float turbidity;
+ float sun_disk_scale;
+ Color ground_color;
+ float exposure;
+ float dither_strength;
+ Ref<Texture2D> night_sky;
+
+protected:
+ static void _bind_methods();
+ virtual bool _can_do_next_pass() const override;
+
+public:
+ void set_rayleigh_coefficient(float p_rayleigh);
+ float get_rayleigh_coefficient() const;
+
+ void set_rayleigh_color(Color p_rayleigh_color);
+ Color get_rayleigh_color() const;
+
+ void set_turbidity(float p_turbidity);
+ float get_turbidity() const;
+
+ void set_mie_coefficient(float p_mie);
+ float get_mie_coefficient() const;
+
+ void set_mie_eccentricity(float p_eccentricity);
+ float get_mie_eccentricity() const;
+
+ void set_mie_color(Color p_mie_color);
+ Color get_mie_color() const;
+
+ void set_sun_disk_scale(float p_sun_disk_scale);
+ float get_sun_disk_scale() const;
+
+ void set_ground_color(Color p_ground_color);
+ Color get_ground_color() const;
+
+ void set_exposure(float p_exposure);
+ float get_exposure() const;
+
+ void set_dither_strength(float p_dither_strength);
+ float get_dither_strength() const;
+
+ void set_night_sky(const Ref<Texture2D> &p_night_sky);
+ Ref<Texture2D> get_night_sky() const;
+
+ virtual Shader::Mode get_shader_mode() const override;
+ RID get_shader_rid() const;
+
+ PhysicalSkyMaterial();
+ ~PhysicalSkyMaterial();
+};
+
+#endif /* !SKY_MATERIAL_H */
diff --git a/scene/resources/space_2d.cpp b/scene/resources/space_2d.cpp
deleted file mode 100644
index 376e926548..0000000000
--- a/scene/resources/space_2d.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*************************************************************************/
-/* space_2d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "space_2d.h"
-
-RID Space2D::get_rid() const {
-
- return space;
-}
-
-void Space2D::set_active(bool p_active) {
-
- active = p_active;
- Physics2DServer::get_singleton()->space_set_active(space, active);
-}
-
-bool Space2D::is_active() const {
-
- return active;
-}
-
-void Space2D::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_active", "active"), &Space2D::set_active);
- ClassDB::bind_method(D_METHOD("is_active"), &Space2D::is_active);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
-}
-
-Space2D::Space2D() {
-
- active = false;
- space = Physics2DServer::get_singleton()->space_create();
-}
-
-Space2D::~Space2D() {
-
- Physics2DServer::get_singleton()->free(space);
-}
diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape_3d.cpp
index f408717834..fd33387df6 100644
--- a/scene/resources/sphere_shape.cpp
+++ b/scene/resources/sphere_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* sphere_shape.cpp */
+/* sphere_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,17 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "sphere_shape.h"
-#include "servers/physics_server.h"
-
-Vector<Vector3> SphereShape::get_debug_mesh_lines() {
+#include "sphere_shape_3d.h"
+#include "servers/physics_server_3d.h"
+Vector<Vector3> SphereShape3D::get_debug_mesh_lines() const {
float r = get_radius();
Vector<Vector3> points;
for (int i = 0; i <= 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
@@ -55,35 +53,34 @@ Vector<Vector3> SphereShape::get_debug_mesh_lines() {
return points;
}
-void SphereShape::_update_shape() {
-
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), radius);
- Shape::_update_shape();
+real_t SphereShape3D::get_enclosing_radius() const {
+ return radius;
}
-void SphereShape::set_radius(float p_radius) {
+void SphereShape3D::_update_shape() {
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), radius);
+ Shape3D::_update_shape();
+}
+void SphereShape3D::set_radius(float p_radius) {
radius = p_radius;
_update_shape();
notify_change_to_owners();
_change_notify("radius");
}
-float SphereShape::get_radius() const {
-
+float SphereShape3D::get_radius() const {
return radius;
}
-void SphereShape::_bind_methods() {
+void SphereShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &SphereShape3D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &SphereShape3D::get_radius);
- ClassDB::bind_method(D_METHOD("set_radius", "radius"), &SphereShape::set_radius);
- ClassDB::bind_method(D_METHOD("get_radius"), &SphereShape::get_radius);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_radius", "get_radius");
}
-SphereShape::SphereShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) {
-
+SphereShape3D::SphereShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_SPHERE)) {
set_radius(1.0);
}
diff --git a/scene/resources/sphere_shape.h b/scene/resources/sphere_shape_3d.h
index 6002a3baeb..5cad67aea5 100644
--- a/scene/resources/sphere_shape.h
+++ b/scene/resources/sphere_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* sphere_shape.h */
+/* sphere_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,28 +28,28 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SPHERE_SHAPE_H
-#define SPHERE_SHAPE_H
+#ifndef SPHERE_SHAPE_3D_H
+#define SPHERE_SHAPE_3D_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class SphereShape : public Shape {
-
- GDCLASS(SphereShape, Shape);
+class SphereShape3D : public Shape3D {
+ GDCLASS(SphereShape3D, Shape3D);
float radius;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
void set_radius(float p_radius);
float get_radius() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override;
- SphereShape();
+ SphereShape3D();
};
#endif // SPHERE_SHAPE_H
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 9408d1aa71..cdb0ec5111 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -29,37 +29,36 @@
/*************************************************************************/
#include "style_box.h"
-#include "scene/2d/canvas_item.h"
+
+#include "scene/main/canvas_item.h"
#include <limits.h>
bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const {
-
return true;
}
void StyleBox::set_default_margin(Margin p_margin, float p_value) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
margin[p_margin] = p_value;
emit_changed();
}
-float StyleBox::get_default_margin(Margin p_margin) const {
+float StyleBox::get_default_margin(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return margin[p_margin];
}
float StyleBox::get_margin(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
- if (margin[p_margin] < 0)
+ if (margin[p_margin] < 0) {
return get_style_margin(p_margin);
- else
+ } else {
return margin[p_margin];
+ }
}
CanvasItem *StyleBox::get_current_item_drawn() const {
@@ -67,17 +66,14 @@ CanvasItem *StyleBox::get_current_item_drawn() const {
}
Size2 StyleBox::get_minimum_size() const {
-
return Size2(get_margin(MARGIN_LEFT) + get_margin(MARGIN_RIGHT), get_margin(MARGIN_TOP) + get_margin(MARGIN_BOTTOM));
}
Point2 StyleBox::get_offset() const {
-
return Point2(get_margin(MARGIN_LEFT), get_margin(MARGIN_TOP));
}
Size2 StyleBox::get_center_size() const {
-
return Size2();
}
@@ -86,7 +82,6 @@ Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const {
}
void StyleBox::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("test_mask", "point", "rect"), &StyleBox::test_mask);
ClassDB::bind_method(D_METHOD("set_default_margin", "margin", "offset"), &StyleBox::set_default_margin);
@@ -104,24 +99,22 @@ void StyleBox::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "rect"), &StyleBox::draw);
ADD_GROUP("Content Margin", "content_margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_left", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_BOTTOM);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_left", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_BOTTOM);
}
StyleBox::StyleBox() {
-
for (int i = 0; i < 4; i++) {
-
margin[i] = -1;
}
}
-void StyleBoxTexture::set_texture(Ref<Texture> p_texture) {
-
- if (texture == p_texture)
+void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) {
+ if (texture == p_texture) {
return;
+ }
texture = p_texture;
if (p_texture.is_null()) {
region_rect = Rect2(0, 0, 0, 0);
@@ -133,26 +126,23 @@ void StyleBoxTexture::set_texture(Ref<Texture> p_texture) {
_change_notify("texture");
}
-Ref<Texture> StyleBoxTexture::get_texture() const {
-
+Ref<Texture2D> StyleBoxTexture::get_texture() const {
return texture;
}
-void StyleBoxTexture::set_normal_map(Ref<Texture> p_normal_map) {
-
- if (normal_map == p_normal_map)
+void StyleBoxTexture::set_normal_map(Ref<Texture2D> p_normal_map) {
+ if (normal_map == p_normal_map) {
return;
+ }
normal_map = p_normal_map;
emit_changed();
}
-Ref<Texture> StyleBoxTexture::get_normal_map() const {
-
+Ref<Texture2D> StyleBoxTexture::get_normal_map() const {
return normal_map;
}
void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
margin[p_margin] = p_size;
@@ -165,15 +155,14 @@ void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) {
};
_change_notify(margin_prop[p_margin]);
}
-float StyleBoxTexture::get_margin_size(Margin p_margin) const {
+float StyleBoxTexture::get_margin_size(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return margin[p_margin];
}
float StyleBoxTexture::get_style_margin(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return margin[p_margin];
@@ -184,8 +173,9 @@ Rect2 StyleBoxTexture::get_draw_rect(const Rect2 &p_rect) const {
}
void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
- if (texture.is_null())
+ if (texture.is_null()) {
return;
+ }
Rect2 rect = p_rect;
Rect2 src_rect = region_rect;
@@ -198,33 +188,31 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
rect.size.y += expand_margin[MARGIN_TOP] + expand_margin[MARGIN_BOTTOM];
RID normal_rid;
- if (normal_map.is_valid())
+ if (normal_map.is_valid()) {
normal_rid = normal_map->get_rid();
+ }
- VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NinePatchAxisMode(axis_h), VS::NinePatchAxisMode(axis_v), draw_center, modulate, normal_rid);
+ RenderingServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), RS::NinePatchAxisMode(axis_h), RS::NinePatchAxisMode(axis_v), draw_center, modulate, normal_rid);
}
void StyleBoxTexture::set_draw_center(bool p_enabled) {
-
draw_center = p_enabled;
emit_changed();
}
bool StyleBoxTexture::is_draw_center_enabled() const {
-
return draw_center;
}
Size2 StyleBoxTexture::get_center_size() const {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return Size2();
+ }
return region_rect.size - get_minimum_size();
}
void StyleBoxTexture::set_expand_margin_size(Margin p_expand_margin, float p_size) {
-
ERR_FAIL_INDEX((int)p_expand_margin, 4);
expand_margin[p_expand_margin] = p_size;
emit_changed();
@@ -240,70 +228,63 @@ void StyleBoxTexture::set_expand_margin_size_individual(float p_left, float p_to
void StyleBoxTexture::set_expand_margin_size_all(float p_expand_margin_size) {
for (int i = 0; i < 4; i++) {
-
expand_margin[i] = p_expand_margin_size;
}
emit_changed();
}
float StyleBoxTexture::get_expand_margin_size(Margin p_expand_margin) const {
-
ERR_FAIL_INDEX_V((int)p_expand_margin, 4, 0);
return expand_margin[p_expand_margin];
}
void StyleBoxTexture::set_region_rect(const Rect2 &p_region_rect) {
-
- if (region_rect == p_region_rect)
+ if (region_rect == p_region_rect) {
return;
+ }
region_rect = p_region_rect;
emit_changed();
+ _change_notify("region");
}
Rect2 StyleBoxTexture::get_region_rect() const {
-
return region_rect;
}
void StyleBoxTexture::set_h_axis_stretch_mode(AxisStretchMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 3);
axis_h = p_mode;
emit_changed();
}
StyleBoxTexture::AxisStretchMode StyleBoxTexture::get_h_axis_stretch_mode() const {
-
return axis_h;
}
void StyleBoxTexture::set_v_axis_stretch_mode(AxisStretchMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 3);
axis_v = p_mode;
emit_changed();
}
StyleBoxTexture::AxisStretchMode StyleBoxTexture::get_v_axis_stretch_mode() const {
-
return axis_v;
}
void StyleBoxTexture::set_modulate(const Color &p_modulate) {
- if (modulate == p_modulate)
+ if (modulate == p_modulate) {
return;
+ }
modulate = p_modulate;
emit_changed();
}
Color StyleBoxTexture::get_modulate() const {
-
return modulate;
}
void StyleBoxTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &StyleBoxTexture::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &StyleBoxTexture::get_texture);
@@ -335,19 +316,19 @@ void StyleBoxTexture::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_GROUP("Margin", "margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_BOTTOM);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_BOTTOM);
ADD_GROUP("Expand Margin", "expand_margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_BOTTOM);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_BOTTOM);
ADD_GROUP("Axis Stretch", "axis_stretch_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode");
@@ -361,7 +342,6 @@ void StyleBoxTexture::_bind_methods() {
}
StyleBoxTexture::StyleBoxTexture() {
-
for (int i = 0; i < 4; i++) {
margin[i] = 0;
expand_margin[i] = 0;
@@ -372,29 +352,27 @@ StyleBoxTexture::StyleBoxTexture() {
axis_h = AXIS_STRETCH_MODE_STRETCH;
axis_v = AXIS_STRETCH_MODE_STRETCH;
}
+
StyleBoxTexture::~StyleBoxTexture() {
}
////////////////
void StyleBoxFlat::set_bg_color(const Color &p_color) {
-
bg_color = p_color;
emit_changed();
}
Color StyleBoxFlat::get_bg_color() const {
-
return bg_color;
}
void StyleBoxFlat::set_border_color(const Color &p_color) {
-
border_color = p_color;
emit_changed();
}
-Color StyleBoxFlat::get_border_color() const {
+Color StyleBoxFlat::get_border_color() const {
return border_color;
}
@@ -405,8 +383,8 @@ void StyleBoxFlat::set_border_width_all(int p_size) {
border_width[3] = p_size;
emit_changed();
}
-int StyleBoxFlat::get_border_width_min() const {
+int StyleBoxFlat::get_border_width_min() const {
return MIN(MIN(border_width[0], border_width[1]), MIN(border_width[2], border_width[3]));
}
@@ -422,23 +400,22 @@ int StyleBoxFlat::get_border_width(Margin p_margin) const {
}
void StyleBoxFlat::set_border_blend(bool p_blend) {
-
blend_border = p_blend;
emit_changed();
}
-bool StyleBoxFlat::get_border_blend() const {
+bool StyleBoxFlat::get_border_blend() const {
return blend_border;
}
void StyleBoxFlat::set_corner_radius_all(int radius) {
-
for (int i = 0; i < 4; i++) {
corner_radius[i] = radius;
}
emit_changed();
}
+
void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_botton_right, const int radius_bottom_left) {
corner_radius[0] = radius_top_left;
corner_radius[1] = radius_top_right;
@@ -447,6 +424,7 @@ void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const
emit_changed();
}
+
int StyleBoxFlat::get_corner_radius_min() const {
int smallest = corner_radius[0];
for (int i = 1; i < 4; i++) {
@@ -458,19 +436,17 @@ int StyleBoxFlat::get_corner_radius_min() const {
}
void StyleBoxFlat::set_corner_radius(const Corner p_corner, const int radius) {
-
ERR_FAIL_INDEX((int)p_corner, 4);
corner_radius[p_corner] = radius;
emit_changed();
}
-int StyleBoxFlat::get_corner_radius(const Corner p_corner) const {
+int StyleBoxFlat::get_corner_radius(const Corner p_corner) const {
ERR_FAIL_INDEX_V((int)p_corner, 4, 0);
return corner_radius[p_corner];
}
void StyleBoxFlat::set_expand_margin_size(Margin p_expand_margin, float p_size) {
-
ERR_FAIL_INDEX((int)p_expand_margin, 4);
expand_margin[p_expand_margin] = p_size;
emit_changed();
@@ -486,54 +462,49 @@ void StyleBoxFlat::set_expand_margin_size_individual(float p_left, float p_top,
void StyleBoxFlat::set_expand_margin_size_all(float p_expand_margin_size) {
for (int i = 0; i < 4; i++) {
-
expand_margin[i] = p_expand_margin_size;
}
emit_changed();
}
float StyleBoxFlat::get_expand_margin_size(Margin p_expand_margin) const {
-
ERR_FAIL_INDEX_V((int)p_expand_margin, 4, 0.0);
return expand_margin[p_expand_margin];
}
-void StyleBoxFlat::set_draw_center(bool p_enabled) {
+void StyleBoxFlat::set_draw_center(bool p_enabled) {
draw_center = p_enabled;
emit_changed();
}
-bool StyleBoxFlat::is_draw_center_enabled() const {
+bool StyleBoxFlat::is_draw_center_enabled() const {
return draw_center;
}
void StyleBoxFlat::set_shadow_color(const Color &p_color) {
-
shadow_color = p_color;
emit_changed();
}
-Color StyleBoxFlat::get_shadow_color() const {
+Color StyleBoxFlat::get_shadow_color() const {
return shadow_color;
}
void StyleBoxFlat::set_shadow_size(const int &p_size) {
-
shadow_size = p_size;
emit_changed();
}
-int StyleBoxFlat::get_shadow_size() const {
+int StyleBoxFlat::get_shadow_size() const {
return shadow_size;
}
void StyleBoxFlat::set_shadow_offset(const Point2 &p_offset) {
-
shadow_offset = p_offset;
emit_changed();
}
-Point2 StyleBoxFlat::get_shadow_offset() const {
+Point2 StyleBoxFlat::get_shadow_offset() const {
return shadow_offset;
}
@@ -541,6 +512,7 @@ void StyleBoxFlat::set_anti_aliased(const bool &p_anti_aliased) {
anti_aliased = p_anti_aliased;
emit_changed();
}
+
bool StyleBoxFlat::is_anti_aliased() const {
return anti_aliased;
}
@@ -549,6 +521,7 @@ void StyleBoxFlat::set_aa_size(const int &p_aa_size) {
aa_size = CLAMP(p_aa_size, 1, 5);
emit_changed();
}
+
int StyleBoxFlat::get_aa_size() const {
return aa_size;
}
@@ -557,12 +530,12 @@ void StyleBoxFlat::set_corner_detail(const int &p_corner_detail) {
corner_detail = CLAMP(p_corner_detail, 1, 20);
emit_changed();
}
+
int StyleBoxFlat::get_corner_detail() const {
return corner_detail;
}
Size2 StyleBoxFlat::get_center_size() const {
-
return Size2();
}
@@ -592,7 +565,6 @@ inline void set_inner_corner_radius(const Rect2 style_rect, const Rect2 inner_re
inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 &style_rect, const int corner_radius[4],
const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const bool fill_center = false) {
-
int vert_offset = verts.size();
if (!vert_offset) {
vert_offset = 0;
@@ -704,7 +676,6 @@ Rect2 StyleBoxFlat::get_draw_rect(const Rect2 &p_rect) const {
}
void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
-
//PREPARATIONS
bool draw_border = (border_width[0] > 0) || (border_width[1] > 0) || (border_width[2] > 0) || (border_width[3] > 0);
bool draw_shadow = (shadow_size > 0);
@@ -852,7 +823,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
}
//DRAWING
- VisualServer *vs = VisualServer::get_singleton();
+ RenderingServer *vs = RenderingServer::get_singleton();
vs->canvas_item_add_triangle_array(p_canvas_item, indices, verts, colors, uvs);
}
@@ -860,8 +831,8 @@ float StyleBoxFlat::get_style_margin(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return border_width[p_margin];
}
-void StyleBoxFlat::_bind_methods() {
+void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &StyleBoxFlat::set_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_color"), &StyleBoxFlat::get_bg_color);
@@ -933,14 +904,14 @@ void StyleBoxFlat::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "corner_detail", PROPERTY_HINT_RANGE, "1,20,1"), "set_corner_detail", "get_corner_detail");
ADD_GROUP("Expand Margin", "expand_margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_BOTTOM);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_BOTTOM);
ADD_GROUP("Shadow", "shadow_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size"), "set_shadow_size", "get_shadow_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_shadow_size", "get_shadow_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shadow_offset"), "set_shadow_offset", "get_shadow_offset");
ADD_GROUP("Anti Aliasing", "anti_aliasing_");
@@ -949,7 +920,6 @@ void StyleBoxFlat::_bind_methods() {
}
StyleBoxFlat::StyleBoxFlat() {
-
bg_color = Color(0.6, 0.6, 0.6);
shadow_color = Color(0, 0, 0, 0.6);
border_color = Color(0.8, 0.8, 0.8);
@@ -978,6 +948,7 @@ StyleBoxFlat::StyleBoxFlat() {
corner_radius[2] = 0;
corner_radius[3] = 0;
}
+
StyleBoxFlat::~StyleBoxFlat() {
}
@@ -985,6 +956,7 @@ void StyleBoxLine::set_color(const Color &p_color) {
color = p_color;
emit_changed();
}
+
Color StyleBoxLine::get_color() const {
return color;
}
@@ -993,6 +965,7 @@ void StyleBoxLine::set_thickness(int p_thickness) {
thickness = p_thickness;
emit_changed();
}
+
int StyleBoxLine::get_thickness() const {
return thickness;
}
@@ -1001,6 +974,7 @@ void StyleBoxLine::set_vertical(bool p_vertical) {
vertical = p_vertical;
emit_changed();
}
+
bool StyleBoxLine::is_vertical() const {
return vertical;
}
@@ -1009,6 +983,7 @@ void StyleBoxLine::set_grow_end(float p_grow_end) {
grow_end = p_grow_end;
emit_changed();
}
+
float StyleBoxLine::get_grow_end() const {
return grow_end;
}
@@ -1017,12 +992,12 @@ void StyleBoxLine::set_grow_begin(float p_grow_begin) {
grow_begin = p_grow_begin;
emit_changed();
}
+
float StyleBoxLine::get_grow_begin() const {
return grow_begin;
}
void StyleBoxLine::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_color", "color"), &StyleBoxLine::set_color);
ClassDB::bind_method(D_METHOD("get_color"), &StyleBoxLine::get_color);
ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &StyleBoxLine::set_thickness);
@@ -1035,21 +1010,23 @@ void StyleBoxLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_vertical"), &StyleBoxLine::is_vertical);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow_begin", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_begin", "get_grow_begin");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow_end", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_end", "get_grow_end");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "grow_begin", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_begin", "get_grow_begin");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "grow_end", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_end", "get_grow_end");
ADD_PROPERTY(PropertyInfo(Variant::INT, "thickness", PROPERTY_HINT_RANGE, "0,10"), "set_thickness", "get_thickness");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical");
}
+
float StyleBoxLine::get_style_margin(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, thickness);
return thickness;
}
+
Size2 StyleBoxLine::get_center_size() const {
return Size2();
}
void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const {
- VisualServer *vs = VisualServer::get_singleton();
+ RenderingServer *vs = RenderingServer::get_singleton();
Rect2i r = p_rect;
if (vertical) {
@@ -1072,4 +1049,5 @@ StyleBoxLine::StyleBoxLine() {
color = Color(0.0, 0.0, 0.0);
vertical = false;
}
+
StyleBoxLine::~StyleBoxLine() {}
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 3e0fffdcd9..3d29e3bd0f 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -33,12 +33,11 @@
#include "core/resource.h"
#include "scene/resources/texture.h"
-#include "servers/visual_server.h"
+#include "servers/rendering_server.h"
class CanvasItem;
class StyleBox : public Resource {
-
GDCLASS(StyleBox, Resource);
RES_BASE_EXTENSION("stylebox");
OBJ_SAVE_TYPE(StyleBox);
@@ -68,17 +67,15 @@ public:
};
class StyleBoxEmpty : public StyleBox {
-
GDCLASS(StyleBoxEmpty, StyleBox);
- virtual float get_style_margin(Margin p_margin) const { return 0; }
+ virtual float get_style_margin(Margin p_margin) const override { return 0; }
public:
- virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const {}
+ virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const override {}
StyleBoxEmpty() {}
};
class StyleBoxTexture : public StyleBox {
-
GDCLASS(StyleBoxTexture, StyleBox);
public:
@@ -92,15 +89,15 @@ private:
float expand_margin[4];
float margin[4];
Rect2 region_rect;
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
bool draw_center;
Color modulate;
AxisStretchMode axis_h;
AxisStretchMode axis_v;
protected:
- virtual float get_style_margin(Margin p_margin) const;
+ virtual float get_style_margin(Margin p_margin) const override;
static void _bind_methods();
public:
@@ -115,15 +112,15 @@ public:
void set_region_rect(const Rect2 &p_region_rect);
Rect2 get_region_rect() const;
- void set_texture(Ref<Texture> p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(Ref<Texture2D> p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_normal_map(Ref<Texture> p_normal_map);
- Ref<Texture> get_normal_map() const;
+ void set_normal_map(Ref<Texture2D> p_normal_map);
+ Ref<Texture2D> get_normal_map() const;
void set_draw_center(bool p_enabled);
bool is_draw_center_enabled() const;
- virtual Size2 get_center_size() const;
+ virtual Size2 get_center_size() const override;
void set_h_axis_stretch_mode(AxisStretchMode p_mode);
AxisStretchMode get_h_axis_stretch_mode() const;
@@ -134,8 +131,8 @@ public:
void set_modulate(const Color &p_modulate);
Color get_modulate() const;
- virtual Rect2 get_draw_rect(const Rect2 &p_rect) const;
- virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const;
+ virtual Rect2 get_draw_rect(const Rect2 &p_rect) const override;
+ virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const override;
StyleBoxTexture();
~StyleBoxTexture();
@@ -144,7 +141,6 @@ public:
VARIANT_ENUM_CAST(StyleBoxTexture::AxisStretchMode)
class StyleBoxFlat : public StyleBox {
-
GDCLASS(StyleBoxFlat, StyleBox);
Color bg_color;
@@ -165,7 +161,7 @@ class StyleBoxFlat : public StyleBox {
int aa_size;
protected:
- virtual float get_style_margin(Margin p_margin) const;
+ virtual float get_style_margin(Margin p_margin) const override;
static void _bind_methods();
public:
@@ -227,10 +223,10 @@ public:
void set_aa_size(const int &p_aa_size);
int get_aa_size() const;
- virtual Size2 get_center_size() const;
+ virtual Size2 get_center_size() const override;
- virtual Rect2 get_draw_rect(const Rect2 &p_rect) const;
- virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const;
+ virtual Rect2 get_draw_rect(const Rect2 &p_rect) const override;
+ virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const override;
StyleBoxFlat();
~StyleBoxFlat();
@@ -238,7 +234,6 @@ public:
// just used to draw lines.
class StyleBoxLine : public StyleBox {
-
GDCLASS(StyleBoxLine, StyleBox);
Color color;
int thickness;
@@ -247,7 +242,7 @@ class StyleBoxLine : public StyleBox {
float grow_end;
protected:
- virtual float get_style_margin(Margin p_margin) const;
+ virtual float get_style_margin(Margin p_margin) const override;
static void _bind_methods();
public:
@@ -266,9 +261,9 @@ public:
void set_grow_end(float p_grow);
float get_grow_end() const;
- virtual Size2 get_center_size() const;
+ virtual Size2 get_center_size() const override;
- virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const;
+ virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const override;
StyleBoxLine();
~StyleBoxLine();
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index f921a9695c..1a2dcc84bb 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -36,43 +36,50 @@
#define EQ_VERTEX_DIST 0.00001
bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const {
-
- if (vertex != p_vertex.vertex)
+ if (vertex != p_vertex.vertex) {
return false;
+ }
- if (uv != p_vertex.uv)
+ if (uv != p_vertex.uv) {
return false;
+ }
- if (uv2 != p_vertex.uv2)
+ if (uv2 != p_vertex.uv2) {
return false;
+ }
- if (normal != p_vertex.normal)
+ if (normal != p_vertex.normal) {
return false;
+ }
- if (binormal != p_vertex.binormal)
+ if (binormal != p_vertex.binormal) {
return false;
+ }
- if (color != p_vertex.color)
+ if (color != p_vertex.color) {
return false;
+ }
- if (bones.size() != p_vertex.bones.size())
+ if (bones.size() != p_vertex.bones.size()) {
return false;
+ }
for (int i = 0; i < bones.size(); i++) {
- if (bones[i] != p_vertex.bones[i])
+ if (bones[i] != p_vertex.bones[i]) {
return false;
+ }
}
for (int i = 0; i < weights.size(); i++) {
- if (weights[i] != p_vertex.weights[i])
+ if (weights[i] != p_vertex.weights[i]) {
return false;
+ }
}
return true;
}
uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
-
uint32_t h = hash_djb2_buffer((const uint8_t *)&p_vtx.vertex, sizeof(real_t) * 3);
h = hash_djb2_buffer((const uint8_t *)&p_vtx.normal, sizeof(real_t) * 3, h);
h = hash_djb2_buffer((const uint8_t *)&p_vtx.binormal, sizeof(real_t) * 3, h);
@@ -86,7 +93,6 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
}
void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) {
-
clear();
primitive = p_primitive;
@@ -95,7 +101,6 @@ void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) {
}
void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
-
ERR_FAIL_COND(!begun);
Vertex vtx;
@@ -159,8 +164,8 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
format |= Mesh::ARRAY_FORMAT_VERTEX;
}
-void SurfaceTool::add_color(Color p_color) {
+void SurfaceTool::add_color(Color p_color) {
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_COLOR));
@@ -168,8 +173,8 @@ void SurfaceTool::add_color(Color p_color) {
format |= Mesh::ARRAY_FORMAT_COLOR;
last_color = p_color;
}
-void SurfaceTool::add_normal(const Vector3 &p_normal) {
+void SurfaceTool::add_normal(const Vector3 &p_normal) {
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_NORMAL));
@@ -179,7 +184,6 @@ void SurfaceTool::add_normal(const Vector3 &p_normal) {
}
void SurfaceTool::add_tangent(const Plane &p_tangent) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TANGENT));
@@ -188,7 +192,6 @@ void SurfaceTool::add_tangent(const Plane &p_tangent) {
}
void SurfaceTool::add_uv(const Vector2 &p_uv) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV));
@@ -197,7 +200,6 @@ void SurfaceTool::add_uv(const Vector2 &p_uv) {
}
void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV2));
@@ -206,7 +208,6 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
}
void SurfaceTool::add_bones(const Vector<int> &p_bones) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES));
@@ -215,7 +216,6 @@ void SurfaceTool::add_bones(const Vector<int> &p_bones) {
}
void SurfaceTool::add_weights(const Vector<float> &p_weights) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS));
@@ -224,12 +224,10 @@ void SurfaceTool::add_weights(const Vector<float> &p_weights) {
}
void SurfaceTool::add_smooth_group(bool p_smooth) {
-
ERR_FAIL_COND(!begun);
if (index_array.size()) {
smooth_groups[index_array.size()] = p_smooth;
} else {
-
smooth_groups[vertex_array.size()] = p_smooth;
}
}
@@ -264,7 +262,6 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect
}
void SurfaceTool::add_index(int p_index) {
-
ERR_FAIL_COND(!begun);
format |= Mesh::ARRAY_FORMAT_INDEX;
@@ -272,29 +269,25 @@ void SurfaceTool::add_index(int p_index) {
}
Array SurfaceTool::commit_to_arrays() {
-
int varr_len = vertex_array.size();
Array a;
a.resize(Mesh::ARRAY_MAX);
for (int i = 0; i < Mesh::ARRAY_MAX; i++) {
-
- if (!(format & (1 << i)))
+ if (!(format & (1 << i))) {
continue; //not in format
+ }
switch (i) {
-
case Mesh::ARRAY_VERTEX:
case Mesh::ARRAY_NORMAL: {
-
- PoolVector<Vector3> array;
+ Vector<Vector3> array;
array.resize(varr_len);
- PoolVector<Vector3>::Write w = array.write();
+ Vector3 *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
-
const Vertex &v = E->get();
switch (i) {
@@ -307,25 +300,21 @@ Array SurfaceTool::commit_to_arrays() {
}
}
- w.release();
a[i] = array;
} break;
case Mesh::ARRAY_TEX_UV:
case Mesh::ARRAY_TEX_UV2: {
-
- PoolVector<Vector2> array;
+ Vector<Vector2> array;
array.resize(varr_len);
- PoolVector<Vector2>::Write w = array.write();
+ Vector2 *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
-
const Vertex &v = E->get();
switch (i) {
-
case Mesh::ARRAY_TEX_UV: {
w[idx] = v.uv;
} break;
@@ -335,18 +324,15 @@ Array SurfaceTool::commit_to_arrays() {
}
}
- w.release();
a[i] = array;
} break;
case Mesh::ARRAY_TANGENT: {
-
- PoolVector<float> array;
+ Vector<float> array;
array.resize(varr_len * 4);
- PoolVector<float>::Write w = array.write();
+ float *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
-
const Vertex &v = E->get();
w[idx + 0] = v.tangent.x;
@@ -358,35 +344,29 @@ Array SurfaceTool::commit_to_arrays() {
w[idx + 3] = d < 0 ? -1 : 1;
}
- w.release();
a[i] = array;
} break;
case Mesh::ARRAY_COLOR: {
-
- PoolVector<Color> array;
+ Vector<Color> array;
array.resize(varr_len);
- PoolVector<Color>::Write w = array.write();
+ Color *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
-
const Vertex &v = E->get();
w[idx] = v.color;
}
- w.release();
a[i] = array;
} break;
case Mesh::ARRAY_BONES: {
-
- PoolVector<int> array;
+ Vector<int> array;
array.resize(varr_len * 4);
- PoolVector<int>::Write w = array.write();
+ int *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
-
const Vertex &v = E->get();
ERR_CONTINUE(v.bones.size() != 4);
@@ -396,48 +376,39 @@ Array SurfaceTool::commit_to_arrays() {
}
}
- w.release();
a[i] = array;
} break;
case Mesh::ARRAY_WEIGHTS: {
-
- PoolVector<float> array;
+ Vector<float> array;
array.resize(varr_len * 4);
- PoolVector<float>::Write w = array.write();
+ float *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
-
const Vertex &v = E->get();
ERR_CONTINUE(v.weights.size() != 4);
for (int j = 0; j < 4; j++) {
-
w[idx + j] = v.weights[j];
}
}
- w.release();
a[i] = array;
} break;
case Mesh::ARRAY_INDEX: {
-
ERR_CONTINUE(index_array.size() == 0);
- PoolVector<int> array;
+ Vector<int> array;
array.resize(index_array.size());
- PoolVector<int>::Write w = array.write();
+ int *w = array.ptrw();
int idx = 0;
for (List<int>::Element *E = index_array.front(); E; E = E->next(), idx++) {
-
w[idx] = E->get();
}
- w.release();
-
a[i] = array;
} break;
@@ -450,40 +421,41 @@ Array SurfaceTool::commit_to_arrays() {
}
Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_flags) {
-
Ref<ArrayMesh> mesh;
- if (p_existing.is_valid())
+ if (p_existing.is_valid()) {
mesh = p_existing;
- else
+ } else {
mesh.instance();
+ }
int varr_len = vertex_array.size();
- if (varr_len == 0)
+ if (varr_len == 0) {
return mesh;
+ }
int surface = mesh->get_surface_count();
Array a = commit_to_arrays();
- mesh->add_surface_from_arrays(primitive, a, Array(), p_flags);
+ mesh->add_surface_from_arrays(primitive, a, Array(), Dictionary(), p_flags);
- if (material.is_valid())
+ if (material.is_valid()) {
mesh->surface_set_material(surface, material);
+ }
return mesh;
}
void SurfaceTool::index() {
-
- if (index_array.size())
+ if (index_array.size()) {
return; //already indexed
+ }
HashMap<Vertex, int, VertexHasher> indices;
List<Vertex> new_vertices;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
-
int *idxptr = indices.getptr(E->get());
int idx;
if (!idxptr) {
@@ -504,19 +476,17 @@ void SurfaceTool::index() {
}
void SurfaceTool::deindex() {
-
- if (index_array.size() == 0)
+ if (index_array.size() == 0) {
return; //nothing to deindex
+ }
Vector<Vertex> varr;
varr.resize(vertex_array.size());
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
-
varr.write[idx++] = E->get();
}
vertex_array.clear();
for (List<int>::Element *E = index_array.front(); E; E = E->next()) {
-
ERR_FAIL_INDEX(E->get(), varr.size());
vertex_array.push_back(varr[E->get()]);
}
@@ -525,95 +495,77 @@ void SurfaceTool::deindex() {
}
void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
-
Array arr = p_existing->surface_get_arrays(p_surface);
- ERR_FAIL_COND(arr.size() != VS::ARRAY_MAX);
+ ERR_FAIL_COND(arr.size() != RS::ARRAY_MAX);
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) {
-
Vector<SurfaceTool::Vertex> ret;
- PoolVector<Vector3> varr = p_arrays[VS::ARRAY_VERTEX];
- PoolVector<Vector3> narr = p_arrays[VS::ARRAY_NORMAL];
- PoolVector<float> tarr = p_arrays[VS::ARRAY_TANGENT];
- PoolVector<Color> carr = p_arrays[VS::ARRAY_COLOR];
- PoolVector<Vector2> uvarr = p_arrays[VS::ARRAY_TEX_UV];
- PoolVector<Vector2> uv2arr = p_arrays[VS::ARRAY_TEX_UV2];
- PoolVector<int> barr = p_arrays[VS::ARRAY_BONES];
- PoolVector<float> warr = p_arrays[VS::ARRAY_WEIGHTS];
+ Vector<Vector3> varr = p_arrays[RS::ARRAY_VERTEX];
+ Vector<Vector3> narr = p_arrays[RS::ARRAY_NORMAL];
+ Vector<float> tarr = p_arrays[RS::ARRAY_TANGENT];
+ Vector<Color> carr = p_arrays[RS::ARRAY_COLOR];
+ Vector<Vector2> uvarr = p_arrays[RS::ARRAY_TEX_UV];
+ Vector<Vector2> uv2arr = p_arrays[RS::ARRAY_TEX_UV2];
+ Vector<int> barr = p_arrays[RS::ARRAY_BONES];
+ Vector<float> warr = p_arrays[RS::ARRAY_WEIGHTS];
int vc = varr.size();
-
- if (vc == 0)
+ if (vc == 0) {
return ret;
- int lformat = 0;
+ }
- PoolVector<Vector3>::Read rv;
+ int lformat = 0;
if (varr.size()) {
- lformat |= VS::ARRAY_FORMAT_VERTEX;
- rv = varr.read();
+ lformat |= RS::ARRAY_FORMAT_VERTEX;
}
- PoolVector<Vector3>::Read rn;
if (narr.size()) {
- lformat |= VS::ARRAY_FORMAT_NORMAL;
- rn = narr.read();
+ lformat |= RS::ARRAY_FORMAT_NORMAL;
}
- PoolVector<float>::Read rt;
if (tarr.size()) {
- lformat |= VS::ARRAY_FORMAT_TANGENT;
- rt = tarr.read();
+ lformat |= RS::ARRAY_FORMAT_TANGENT;
}
- PoolVector<Color>::Read rc;
if (carr.size()) {
- lformat |= VS::ARRAY_FORMAT_COLOR;
- rc = carr.read();
+ lformat |= RS::ARRAY_FORMAT_COLOR;
}
-
- PoolVector<Vector2>::Read ruv;
if (uvarr.size()) {
- lformat |= VS::ARRAY_FORMAT_TEX_UV;
- ruv = uvarr.read();
+ lformat |= RS::ARRAY_FORMAT_TEX_UV;
}
-
- PoolVector<Vector2>::Read ruv2;
if (uv2arr.size()) {
- lformat |= VS::ARRAY_FORMAT_TEX_UV2;
- ruv2 = uv2arr.read();
+ lformat |= RS::ARRAY_FORMAT_TEX_UV2;
}
-
- PoolVector<int>::Read rb;
if (barr.size()) {
- lformat |= VS::ARRAY_FORMAT_BONES;
- rb = barr.read();
+ lformat |= RS::ARRAY_FORMAT_BONES;
}
-
- PoolVector<float>::Read rw;
if (warr.size()) {
- lformat |= VS::ARRAY_FORMAT_WEIGHTS;
- rw = warr.read();
+ lformat |= RS::ARRAY_FORMAT_WEIGHTS;
}
for (int i = 0; i < vc; i++) {
-
Vertex v;
- if (lformat & VS::ARRAY_FORMAT_VERTEX)
+ if (lformat & RS::ARRAY_FORMAT_VERTEX) {
v.vertex = varr[i];
- if (lformat & VS::ARRAY_FORMAT_NORMAL)
+ }
+ if (lformat & RS::ARRAY_FORMAT_NORMAL) {
v.normal = narr[i];
- if (lformat & VS::ARRAY_FORMAT_TANGENT) {
+ }
+ if (lformat & RS::ARRAY_FORMAT_TANGENT) {
Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]);
v.tangent = p.normal;
v.binormal = p.normal.cross(v.tangent).normalized() * p.d;
}
- if (lformat & VS::ARRAY_FORMAT_COLOR)
+ if (lformat & RS::ARRAY_FORMAT_COLOR) {
v.color = carr[i];
- if (lformat & VS::ARRAY_FORMAT_TEX_UV)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV) {
v.uv = uvarr[i];
- if (lformat & VS::ARRAY_FORMAT_TEX_UV2)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV2) {
v.uv2 = uv2arr[i];
- if (lformat & VS::ARRAY_FORMAT_BONES) {
+ }
+ if (lformat & RS::ARRAY_FORMAT_BONES) {
Vector<int> b;
b.resize(4);
b.write[0] = barr[i * 4 + 0];
@@ -622,7 +574,7 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
b.write[3] = barr[i * 4 + 3];
v.bones = b;
}
- if (lformat & VS::ARRAY_FORMAT_WEIGHTS) {
+ if (lformat & RS::ARRAY_FORMAT_WEIGHTS) {
Vector<float> w;
w.resize(4);
w.write[0] = warr[i * 4 + 0];
@@ -639,86 +591,69 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
}
void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
-
- PoolVector<Vector3> varr = arr[VS::ARRAY_VERTEX];
- PoolVector<Vector3> narr = arr[VS::ARRAY_NORMAL];
- PoolVector<float> tarr = arr[VS::ARRAY_TANGENT];
- PoolVector<Color> carr = arr[VS::ARRAY_COLOR];
- PoolVector<Vector2> uvarr = arr[VS::ARRAY_TEX_UV];
- PoolVector<Vector2> uv2arr = arr[VS::ARRAY_TEX_UV2];
- PoolVector<int> barr = arr[VS::ARRAY_BONES];
- PoolVector<float> warr = arr[VS::ARRAY_WEIGHTS];
+ Vector<Vector3> varr = arr[RS::ARRAY_VERTEX];
+ Vector<Vector3> narr = arr[RS::ARRAY_NORMAL];
+ Vector<float> tarr = arr[RS::ARRAY_TANGENT];
+ Vector<Color> carr = arr[RS::ARRAY_COLOR];
+ Vector<Vector2> uvarr = arr[RS::ARRAY_TEX_UV];
+ Vector<Vector2> uv2arr = arr[RS::ARRAY_TEX_UV2];
+ Vector<int> barr = arr[RS::ARRAY_BONES];
+ Vector<float> warr = arr[RS::ARRAY_WEIGHTS];
int vc = varr.size();
-
- if (vc == 0)
+ if (vc == 0) {
return;
- lformat = 0;
+ }
- PoolVector<Vector3>::Read rv;
+ lformat = 0;
if (varr.size()) {
- lformat |= VS::ARRAY_FORMAT_VERTEX;
- rv = varr.read();
+ lformat |= RS::ARRAY_FORMAT_VERTEX;
}
- PoolVector<Vector3>::Read rn;
if (narr.size()) {
- lformat |= VS::ARRAY_FORMAT_NORMAL;
- rn = narr.read();
+ lformat |= RS::ARRAY_FORMAT_NORMAL;
}
- PoolVector<float>::Read rt;
if (tarr.size()) {
- lformat |= VS::ARRAY_FORMAT_TANGENT;
- rt = tarr.read();
+ lformat |= RS::ARRAY_FORMAT_TANGENT;
}
- PoolVector<Color>::Read rc;
if (carr.size()) {
- lformat |= VS::ARRAY_FORMAT_COLOR;
- rc = carr.read();
+ lformat |= RS::ARRAY_FORMAT_COLOR;
}
-
- PoolVector<Vector2>::Read ruv;
if (uvarr.size()) {
- lformat |= VS::ARRAY_FORMAT_TEX_UV;
- ruv = uvarr.read();
+ lformat |= RS::ARRAY_FORMAT_TEX_UV;
}
-
- PoolVector<Vector2>::Read ruv2;
if (uv2arr.size()) {
- lformat |= VS::ARRAY_FORMAT_TEX_UV2;
- ruv2 = uv2arr.read();
+ lformat |= RS::ARRAY_FORMAT_TEX_UV2;
}
-
- PoolVector<int>::Read rb;
if (barr.size()) {
- lformat |= VS::ARRAY_FORMAT_BONES;
- rb = barr.read();
+ lformat |= RS::ARRAY_FORMAT_BONES;
}
-
- PoolVector<float>::Read rw;
if (warr.size()) {
- lformat |= VS::ARRAY_FORMAT_WEIGHTS;
- rw = warr.read();
+ lformat |= RS::ARRAY_FORMAT_WEIGHTS;
}
for (int i = 0; i < vc; i++) {
-
Vertex v;
- if (lformat & VS::ARRAY_FORMAT_VERTEX)
+ if (lformat & RS::ARRAY_FORMAT_VERTEX) {
v.vertex = varr[i];
- if (lformat & VS::ARRAY_FORMAT_NORMAL)
+ }
+ if (lformat & RS::ARRAY_FORMAT_NORMAL) {
v.normal = narr[i];
- if (lformat & VS::ARRAY_FORMAT_TANGENT) {
+ }
+ if (lformat & RS::ARRAY_FORMAT_TANGENT) {
Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]);
v.tangent = p.normal;
v.binormal = p.normal.cross(v.tangent).normalized() * p.d;
}
- if (lformat & VS::ARRAY_FORMAT_COLOR)
+ if (lformat & RS::ARRAY_FORMAT_COLOR) {
v.color = carr[i];
- if (lformat & VS::ARRAY_FORMAT_TEX_UV)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV) {
v.uv = uvarr[i];
- if (lformat & VS::ARRAY_FORMAT_TEX_UV2)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV2) {
v.uv2 = uv2arr[i];
- if (lformat & VS::ARRAY_FORMAT_BONES) {
+ }
+ if (lformat & RS::ARRAY_FORMAT_BONES) {
Vector<int> b;
b.resize(4);
b.write[0] = barr[i * 4 + 0];
@@ -727,7 +662,7 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
b.write[3] = barr[i * 4 + 3];
v.bones = b;
}
- if (lformat & VS::ARRAY_FORMAT_WEIGHTS) {
+ if (lformat & RS::ARRAY_FORMAT_WEIGHTS) {
Vector<float> w;
w.resize(4);
w.write[0] = warr[i * 4 + 0];
@@ -742,12 +677,11 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
//indices
- PoolVector<int> idx = arr[VS::ARRAY_INDEX];
+ Vector<int> idx = arr[RS::ARRAY_INDEX];
int is = idx.size();
if (is) {
-
- lformat |= VS::ARRAY_FORMAT_INDEX;
- PoolVector<int>::Read iarr = idx.read();
+ lformat |= RS::ARRAY_FORMAT_INDEX;
+ const int *iarr = idx.ptr();
for (int i = 0; i < is; i++) {
r_index->push_back(iarr[i]);
}
@@ -755,14 +689,12 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
}
void SurfaceTool::create_from_triangle_arrays(const Array &p_arrays) {
-
clear();
primitive = Mesh::PRIMITIVE_TRIANGLES;
_create_list_from_arrays(p_arrays, &vertex_array, &index_array, format);
}
void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) {
-
clear();
primitive = p_existing->surface_get_primitive_type(p_surface);
_create_list(p_existing, p_surface, &vertex_array, &index_array, format);
@@ -785,12 +717,11 @@ void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_sur
ERR_FAIL_COND(shape_idx == -1);
ERR_FAIL_COND(shape_idx >= arr.size());
Array mesh = arr[shape_idx];
- ERR_FAIL_COND(mesh.size() != VS::ARRAY_MAX);
+ ERR_FAIL_COND(mesh.size() != RS::ARRAY_MAX);
_create_list_from_arrays(arr[shape_idx], &vertex_array, &index_array, format);
}
void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform) {
-
if (vertex_array.size() == 0) {
primitive = p_existing->surface_get_primitive_type(p_surface);
format = 0;
@@ -804,13 +735,12 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
int vfrom = vertex_array.size();
for (List<Vertex>::Element *E = nvertices.front(); E; E = E->next()) {
-
Vertex v = E->get();
v.vertex = p_xform.xform(v.vertex);
- if (nformat & VS::ARRAY_FORMAT_NORMAL) {
+ if (nformat & RS::ARRAY_FORMAT_NORMAL) {
v.normal = p_xform.basis.xform(v.normal);
}
- if (nformat & VS::ARRAY_FORMAT_TANGENT) {
+ if (nformat & RS::ARRAY_FORMAT_TANGENT) {
v.tangent = p_xform.basis.xform(v.tangent);
v.binormal = p_xform.basis.xform(v.binormal);
}
@@ -819,7 +749,6 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
}
for (List<int>::Element *E = nindices.front(); E; E = E->next()) {
-
int dst_index = E->get() + vfrom;
index_array.push_back(dst_index);
}
@@ -837,7 +766,6 @@ struct TangentGenerationContextUserData {
} // namespace
int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
-
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
if (triangle_data.indices.size() > 0) {
@@ -846,12 +774,12 @@ int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
return triangle_data.vertices.size() / 3;
}
}
-int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
+int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
return 3; //always 3
}
-void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
+void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
Vector3 v;
if (triangle_data.indices.size() > 0) {
@@ -869,7 +797,6 @@ void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvP
}
void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) {
-
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
Vector3 v;
if (triangle_data.indices.size() > 0) {
@@ -885,8 +812,8 @@ void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNor
fvNormOut[1] = v.y;
fvNormOut[2] = v.z;
}
-void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
+void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
Vector2 v;
if (triangle_data.indices.size() > 0) {
@@ -904,9 +831,8 @@ void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvT
void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
-
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
- Vertex *vtx = NULL;
+ Vertex *vtx = nullptr;
if (triangle_data.indices.size() > 0) {
int index = triangle_data.indices[iFace * 3 + iVert]->get();
if (index < triangle_data.vertices.size()) {
@@ -916,14 +842,13 @@ void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, cons
vtx = &triangle_data.vertices[iFace * 3 + iVert]->get();
}
- if (vtx != NULL) {
+ if (vtx != nullptr) {
vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
vtx->binormal = Vector3(-fvBiTangent[0], -fvBiTangent[1], -fvBiTangent[2]); // for some reason these are reversed, something with the coordinate system in Godot
}
}
void SurfaceTool::generate_tangents() {
-
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_TEX_UV));
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_NORMAL));
@@ -934,7 +859,7 @@ void SurfaceTool::generate_tangents() {
mkif.m_getPosition = mikktGetPosition;
mkif.m_getTexCoord = mikktGetTexCoord;
mkif.m_setTSpace = mikktSetTSpaceDefault;
- mkif.m_setTSpaceBasic = NULL;
+ mkif.m_setTSpaceBasic = nullptr;
SMikkTSpaceContext msc;
msc.m_pInterface = &mkif;
@@ -961,7 +886,6 @@ void SurfaceTool::generate_tangents() {
}
void SurfaceTool::generate_normals(bool p_flip) {
-
ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES);
bool was_indexed = index_array.size();
@@ -972,12 +896,12 @@ void SurfaceTool::generate_normals(bool p_flip) {
int count = 0;
bool smooth = false;
- if (smooth_groups.has(0))
+ if (smooth_groups.has(0)) {
smooth = smooth_groups[0];
+ }
List<Vertex>::Element *B = vertex_array.front();
for (List<Vertex>::Element *E = B; E;) {
-
List<Vertex>::Element *v[3];
v[0] = E;
v[1] = v[0]->next();
@@ -987,15 +911,14 @@ void SurfaceTool::generate_normals(bool p_flip) {
E = v[2]->next();
Vector3 normal;
- if (!p_flip)
+ if (!p_flip) {
normal = Plane(v[0]->get().vertex, v[1]->get().vertex, v[2]->get().vertex).normal;
- else
+ } else {
normal = Plane(v[2]->get().vertex, v[1]->get().vertex, v[0]->get().vertex).normal;
+ }
if (smooth) {
-
for (int i = 0; i < 3; i++) {
-
Vector3 *lv = vertex_hash.getptr(v[i]->get());
if (!lv) {
vertex_hash.set(v[i]->get(), normal);
@@ -1004,20 +927,15 @@ void SurfaceTool::generate_normals(bool p_flip) {
}
}
} else {
-
for (int i = 0; i < 3; i++) {
-
v[i]->get().normal = normal;
}
}
count += 3;
if (smooth_groups.has(count) || !E) {
-
if (vertex_hash.size()) {
-
while (B != E) {
-
Vector3 *lv = vertex_hash.getptr(B->get());
if (lv) {
B->get().normal = lv->normalized();
@@ -1046,12 +964,10 @@ void SurfaceTool::generate_normals(bool p_flip) {
}
void SurfaceTool::set_material(const Ref<Material> &p_material) {
-
material = p_material;
}
void SurfaceTool::clear() {
-
begun = false;
primitive = Mesh::PRIMITIVE_LINES;
format = 0;
@@ -1064,7 +980,6 @@ void SurfaceTool::clear() {
}
void SurfaceTool::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin);
ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex);
@@ -1098,7 +1013,6 @@ void SurfaceTool::_bind_methods() {
}
SurfaceTool::SurfaceTool() {
-
first = false;
begun = false;
primitive = Mesh::PRIMITIVE_LINES;
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 89034f656d..d7b255e695 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -36,12 +36,10 @@
#include "thirdparty/misc/mikktspace.h"
class SurfaceTool : public Reference {
-
GDCLASS(SurfaceTool, Reference);
public:
struct Vertex {
-
Vector3 vertex;
Color color;
Vector3 normal; // normal, binormal, tangent
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
new file mode 100644
index 0000000000..5d58e71fc5
--- /dev/null
+++ b/scene/resources/syntax_highlighter.cpp
@@ -0,0 +1,636 @@
+/*************************************************************************/
+/* syntax_highlighter.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "syntax_highlighter.h"
+
+#include "core/script_language.h"
+#include "scene/gui/text_edit.h"
+
+Dictionary SyntaxHighlighter::get_line_syntax_highlighting(int p_line) {
+ if (highlighting_cache.has(p_line)) {
+ return highlighting_cache[p_line];
+ }
+
+ Dictionary color_map;
+ if (text_edit == nullptr) {
+ return color_map;
+ }
+
+ ScriptInstance *si = get_script_instance();
+ if (si && si->has_method("_get_line_syntax_highlighting")) {
+ color_map = si->call("_get_line_syntax_highlighting", p_line);
+ } else {
+ color_map = _get_line_syntax_highlighting(p_line);
+ }
+ highlighting_cache[p_line] = color_map;
+ return color_map;
+}
+
+void SyntaxHighlighter::_lines_edited_from(int p_from_line, int p_to_line) {
+ if (highlighting_cache.size() < 1) {
+ return;
+ }
+
+ int cache_size = highlighting_cache.back()->key();
+ for (int i = MIN(p_from_line, p_to_line) - 1; i <= cache_size; i++) {
+ if (highlighting_cache.has(i)) {
+ highlighting_cache.erase(i);
+ }
+ }
+}
+
+void SyntaxHighlighter::clear_highlighting_cache() {
+ highlighting_cache.clear();
+
+ ScriptInstance *si = get_script_instance();
+ if (si && si->has_method("_clear_highlighting_cache")) {
+ si->call("_clear_highlighting_cache");
+ return;
+ }
+ _clear_highlighting_cache();
+}
+
+void SyntaxHighlighter::update_cache() {
+ clear_highlighting_cache();
+
+ if (text_edit == nullptr) {
+ return;
+ }
+ ScriptInstance *si = get_script_instance();
+ if (si && si->has_method("_update_cache")) {
+ si->call("_update_cache");
+ return;
+ }
+ _update_cache();
+}
+
+void SyntaxHighlighter::set_text_edit(TextEdit *p_text_edit) {
+ if (text_edit && ObjectDB::get_instance(text_edit_instance_id)) {
+ text_edit->disconnect("lines_edited_from", callable_mp(this, &SyntaxHighlighter::_lines_edited_from));
+ }
+
+ text_edit = p_text_edit;
+ if (p_text_edit == nullptr) {
+ return;
+ }
+ text_edit_instance_id = text_edit->get_instance_id();
+ text_edit->connect("lines_edited_from", callable_mp(this, &SyntaxHighlighter::_lines_edited_from));
+ update_cache();
+}
+
+TextEdit *SyntaxHighlighter::get_text_edit() {
+ return text_edit;
+}
+
+void SyntaxHighlighter::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::get_line_syntax_highlighting);
+ ClassDB::bind_method(D_METHOD("update_cache"), &SyntaxHighlighter::update_cache);
+ ClassDB::bind_method(D_METHOD("clear_highlighting_cache"), &SyntaxHighlighter::clear_highlighting_cache);
+ ClassDB::bind_method(D_METHOD("get_text_edit"), &SyntaxHighlighter::get_text_edit);
+
+ ClassDB::bind_method(D_METHOD("_get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::_get_line_syntax_highlighting);
+ ClassDB::bind_method(D_METHOD("_update_cache"), &SyntaxHighlighter::_update_cache);
+ ClassDB::bind_method(D_METHOD("_clear_highlighting_cache"), &SyntaxHighlighter::_clear_highlighting_cache);
+
+ BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "p_line")));
+ BIND_VMETHOD(MethodInfo("_update_cache"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static bool _is_char(char32_t c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+}
+
+static bool _is_hex_symbol(char32_t c) {
+ return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
+}
+
+Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) {
+ Dictionary color_map;
+
+ bool prev_is_char = false;
+ bool prev_is_number = false;
+ bool in_keyword = false;
+ bool in_word = false;
+ bool in_function_name = false;
+ bool in_member_variable = false;
+ bool is_hex_notation = false;
+ Color keyword_color;
+ Color color;
+
+ color_region_cache[p_line] = -1;
+ int in_region = -1;
+ if (p_line != 0) {
+ if (!color_region_cache.has(p_line - 1)) {
+ get_line_syntax_highlighting(p_line - 1);
+ }
+ in_region = color_region_cache[p_line - 1];
+ }
+
+ const String &str = text_edit->get_line(p_line);
+ const int line_length = str.length();
+ Color prev_color;
+
+ if (in_region != -1 && str.length() == 0) {
+ color_region_cache[p_line] = in_region;
+ }
+ for (int j = 0; j < line_length; j++) {
+ Dictionary highlighter_info;
+
+ color = font_color;
+ bool is_char = !is_symbol(str[j]);
+ bool is_a_symbol = is_symbol(str[j]);
+ bool is_number = (str[j] >= '0' && str[j] <= '9');
+
+ /* color regions */
+ if (is_a_symbol || in_region != -1) {
+ int from = j;
+ for (; from < line_length; from++) {
+ if (str[from] == '\\') {
+ from++;
+ continue;
+ }
+ break;
+ }
+
+ if (from != line_length) {
+ /* check if we are in entering a region */
+ if (in_region == -1) {
+ for (int c = 0; c < color_regions.size(); c++) {
+ /* check there is enough room */
+ int chars_left = line_length - from;
+ int start_key_length = color_regions[c].start_key.length();
+ int end_key_length = color_regions[c].end_key.length();
+ if (chars_left < start_key_length) {
+ continue;
+ }
+
+ /* search the line */
+ bool match = true;
+ const char32_t *start_key = color_regions[c].start_key.get_data();
+ for (int k = 0; k < start_key_length; k++) {
+ if (start_key[k] != str[from + k]) {
+ match = false;
+ break;
+ }
+ }
+ if (!match) {
+ continue;
+ }
+ in_region = c;
+ from += start_key_length;
+
+ /* check if it's the whole line */
+ if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
+ prev_color = color_regions[in_region].color;
+ highlighter_info["color"] = color_regions[c].color;
+ color_map[j] = highlighter_info;
+
+ j = line_length;
+ if (!color_regions[c].line_only) {
+ color_region_cache[p_line] = c;
+ }
+ }
+ break;
+ }
+
+ if (j == line_length) {
+ continue;
+ }
+ }
+
+ /* if we are in one find the end key */
+ if (in_region != -1) {
+ /* search the line */
+ int region_end_index = -1;
+ int end_key_length = color_regions[in_region].end_key.length();
+ const char32_t *end_key = color_regions[in_region].end_key.get_data();
+ for (; from < line_length; from++) {
+ if (line_length - from < end_key_length) {
+ break;
+ }
+
+ if (!is_symbol(str[from])) {
+ continue;
+ }
+
+ if (str[from] == '\\') {
+ from++;
+ continue;
+ }
+
+ region_end_index = from;
+ for (int k = 0; k < end_key_length; k++) {
+ if (end_key[k] != str[from + k]) {
+ region_end_index = -1;
+ break;
+ }
+ }
+
+ if (region_end_index != -1) {
+ break;
+ }
+ }
+
+ prev_color = color_regions[in_region].color;
+ highlighter_info["color"] = color_regions[in_region].color;
+ color_map[j] = highlighter_info;
+
+ j = from + (end_key_length - 1);
+ if (region_end_index == -1) {
+ color_region_cache[p_line] = in_region;
+ }
+
+ in_region = -1;
+ prev_is_char = false;
+ prev_is_number = false;
+ continue;
+ }
+ }
+ }
+
+ // Allow ABCDEF in hex notation.
+ if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) {
+ is_number = true;
+ } else {
+ is_hex_notation = false;
+ }
+
+ // Check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation.
+ if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
+ is_number = true;
+ is_a_symbol = false;
+ is_char = false;
+
+ if (str[j] == 'x' && str[j - 1] == '0') {
+ is_hex_notation = true;
+ }
+ }
+
+ if (!in_word && _is_char(str[j]) && !is_number) {
+ in_word = true;
+ }
+
+ if ((in_keyword || in_word) && !is_hex_notation) {
+ is_number = false;
+ }
+
+ if (is_a_symbol && str[j] != '.' && in_word) {
+ in_word = false;
+ }
+
+ if (!is_char) {
+ in_keyword = false;
+ }
+
+ if (!in_keyword && is_char && !prev_is_char) {
+ int to = j;
+ while (to < line_length && !is_symbol(str[to])) {
+ to++;
+ }
+
+ String word = str.substr(j, to - j);
+ Color col = Color();
+ if (keywords.has(word)) {
+ col = keywords[word];
+ } else if (member_keywords.has(word)) {
+ col = member_keywords[word];
+ for (int k = j - 1; k >= 0; k--) {
+ if (str[k] == '.') {
+ col = Color(); //member indexing not allowed
+ break;
+ } else if (str[k] > 32) {
+ break;
+ }
+ }
+ }
+
+ if (col != Color()) {
+ in_keyword = true;
+ keyword_color = col;
+ }
+ }
+
+ if (!in_function_name && in_word && !in_keyword) {
+ int k = j;
+ while (k < line_length && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
+ k++;
+ }
+
+ // Check for space between name and bracket.
+ while (k < line_length && (str[k] == '\t' || str[k] == ' ')) {
+ k++;
+ }
+
+ if (str[k] == '(') {
+ in_function_name = true;
+ }
+ }
+
+ if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) {
+ int k = j;
+ while (k > 0 && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
+ k--;
+ }
+
+ if (str[k] == '.') {
+ in_member_variable = true;
+ }
+ }
+
+ if (is_a_symbol) {
+ in_function_name = false;
+ in_member_variable = false;
+ }
+
+ if (in_keyword) {
+ color = keyword_color;
+ } else if (in_member_variable) {
+ color = member_color;
+ } else if (in_function_name) {
+ color = function_color;
+ } else if (is_a_symbol) {
+ color = symbol_color;
+ } else if (is_number) {
+ color = number_color;
+ }
+
+ prev_is_char = is_char;
+ prev_is_number = is_number;
+
+ if (color != prev_color) {
+ prev_color = color;
+ highlighter_info["color"] = color;
+ color_map[j] = highlighter_info;
+ }
+ }
+
+ return color_map;
+}
+
+void CodeHighlighter::_clear_highlighting_cache() {
+ color_region_cache.clear();
+}
+
+void CodeHighlighter::_update_cache() {
+ font_color = text_edit->get_theme_color("font_color");
+}
+
+void CodeHighlighter::add_keyword_color(const String &p_keyword, const Color &p_color) {
+ keywords[p_keyword] = p_color;
+ clear_highlighting_cache();
+}
+
+void CodeHighlighter::remove_keyword_color(const String &p_keyword) {
+ keywords.erase(p_keyword);
+ clear_highlighting_cache();
+}
+
+bool CodeHighlighter::has_keyword_color(const String &p_keyword) const {
+ return keywords.has(p_keyword);
+}
+
+Color CodeHighlighter::get_keyword_color(const String &p_keyword) const {
+ ERR_FAIL_COND_V(!keywords.has(p_keyword), Color());
+ return keywords[p_keyword];
+}
+
+void CodeHighlighter::set_keyword_colors(const Dictionary p_keywords) {
+ keywords.clear();
+ keywords = p_keywords;
+ clear_highlighting_cache();
+}
+
+void CodeHighlighter::clear_keyword_colors() {
+ keywords.clear();
+ clear_highlighting_cache();
+}
+
+Dictionary CodeHighlighter::get_keyword_colors() const {
+ return keywords;
+}
+
+void CodeHighlighter::add_member_keyword_color(const String &p_member_keyword, const Color &p_color) {
+ member_keywords[p_member_keyword] = p_color;
+ clear_highlighting_cache();
+}
+
+void CodeHighlighter::remove_member_keyword_color(const String &p_member_keyword) {
+ member_keywords.erase(p_member_keyword);
+ clear_highlighting_cache();
+}
+
+bool CodeHighlighter::has_member_keyword_color(const String &p_member_keyword) const {
+ return member_keywords.has(p_member_keyword);
+}
+
+Color CodeHighlighter::get_member_keyword_color(const String &p_member_keyword) const {
+ ERR_FAIL_COND_V(!member_keywords.has(p_member_keyword), Color());
+ return member_keywords[p_member_keyword];
+}
+
+void CodeHighlighter::set_member_keyword_colors(const Dictionary &p_member_keywords) {
+ member_keywords.clear();
+ member_keywords = p_member_keywords;
+ clear_highlighting_cache();
+}
+
+void CodeHighlighter::clear_member_keyword_colors() {
+ member_keywords.clear();
+ clear_highlighting_cache();
+}
+
+Dictionary CodeHighlighter::get_member_keyword_colors() const {
+ return member_keywords;
+}
+
+void CodeHighlighter::add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only) {
+ for (int i = 0; i < p_start_key.length(); i++) {
+ ERR_FAIL_COND_MSG(!is_symbol(p_start_key[i]), "color regions must start with a symbol");
+ }
+
+ if (p_end_key.length() > 0) {
+ for (int i = 0; i < p_end_key.length(); i++) {
+ ERR_FAIL_COND_MSG(!is_symbol(p_end_key[i]), "color regions must end with a symbol");
+ }
+ }
+
+ int at = 0;
+ for (int i = 0; i < color_regions.size(); i++) {
+ ERR_FAIL_COND_MSG(color_regions[i].start_key == p_start_key, "color region with start key '" + p_start_key + "' already exists.");
+ if (p_start_key.length() < color_regions[i].start_key.length()) {
+ at++;
+ }
+ }
+
+ ColorRegion color_region;
+ color_region.color = p_color;
+ color_region.start_key = p_start_key;
+ color_region.end_key = p_end_key;
+ color_region.line_only = p_line_only || p_end_key == "";
+ color_regions.insert(at, color_region);
+ clear_highlighting_cache();
+}
+
+void CodeHighlighter::remove_color_region(const String &p_start_key) {
+ for (int i = 0; i < color_regions.size(); i++) {
+ if (color_regions[i].start_key == p_start_key) {
+ color_regions.remove(i);
+ break;
+ }
+ }
+ clear_highlighting_cache();
+}
+
+bool CodeHighlighter::has_color_region(const String &p_start_key) const {
+ for (int i = 0; i < color_regions.size(); i++) {
+ if (color_regions[i].start_key == p_start_key) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void CodeHighlighter::set_color_regions(const Dictionary &p_color_regions) {
+ color_regions.clear();
+
+ List<Variant> keys;
+ p_color_regions.get_key_list(&keys);
+
+ for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
+ String key = E->get();
+
+ String start_key = key.get_slice(" ", 0);
+ String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String();
+
+ add_color_region(start_key, end_key, p_color_regions[key], end_key == "");
+ }
+ clear_highlighting_cache();
+}
+
+void CodeHighlighter::clear_color_regions() {
+ color_regions.clear();
+ clear_highlighting_cache();
+}
+
+Dictionary CodeHighlighter::get_color_regions() const {
+ Dictionary r_color_regions;
+ for (int i = 0; i < color_regions.size(); i++) {
+ ColorRegion region = color_regions[i];
+ r_color_regions[region.start_key + (region.end_key.empty() ? "" : " " + region.end_key)] = region.color;
+ }
+ return r_color_regions;
+}
+
+void CodeHighlighter::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_keyword_color", "keyword", "color"), &CodeHighlighter::add_keyword_color);
+ ClassDB::bind_method(D_METHOD("remove_keyword_color", "keyword"), &CodeHighlighter::remove_keyword_color);
+ ClassDB::bind_method(D_METHOD("has_keyword_color", "keyword"), &CodeHighlighter::has_keyword_color);
+ ClassDB::bind_method(D_METHOD("get_keyword_color", "keyword"), &CodeHighlighter::get_keyword_color);
+
+ ClassDB::bind_method(D_METHOD("set_keyword_colors", "keywords"), &CodeHighlighter::set_keyword_colors);
+ ClassDB::bind_method(D_METHOD("clear_keyword_colors"), &CodeHighlighter::clear_keyword_colors);
+ ClassDB::bind_method(D_METHOD("get_keyword_colors"), &CodeHighlighter::get_keyword_colors);
+
+ ClassDB::bind_method(D_METHOD("add_member_keyword_color", "member_keyword", "color"), &CodeHighlighter::add_member_keyword_color);
+ ClassDB::bind_method(D_METHOD("remove_member_keyword_color", "member_keyword"), &CodeHighlighter::remove_member_keyword_color);
+ ClassDB::bind_method(D_METHOD("has_member_keyword_color", "member_keyword"), &CodeHighlighter::has_member_keyword_color);
+ ClassDB::bind_method(D_METHOD("get_member_keyword_color", "member_keyword"), &CodeHighlighter::get_member_keyword_color);
+
+ ClassDB::bind_method(D_METHOD("set_member_keyword_colors", "member_keyword"), &CodeHighlighter::set_member_keyword_colors);
+ ClassDB::bind_method(D_METHOD("clear_member_keyword_colors"), &CodeHighlighter::clear_member_keyword_colors);
+ ClassDB::bind_method(D_METHOD("get_member_keyword_colors"), &CodeHighlighter::get_member_keyword_colors);
+
+ ClassDB::bind_method(D_METHOD("add_color_region", "p_start_key", "p_end_key", "p_color", "p_line_only"), &CodeHighlighter::add_color_region, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("remove_color_region", "p_start_key"), &CodeHighlighter::remove_color_region);
+ ClassDB::bind_method(D_METHOD("has_color_region", "p_start_key"), &CodeHighlighter::has_color_region);
+
+ ClassDB::bind_method(D_METHOD("set_color_regions", "p_color_regions"), &CodeHighlighter::set_color_regions);
+ ClassDB::bind_method(D_METHOD("clear_color_regions"), &CodeHighlighter::clear_color_regions);
+ ClassDB::bind_method(D_METHOD("get_color_regions"), &CodeHighlighter::get_color_regions);
+
+ ClassDB::bind_method(D_METHOD("set_function_color", "color"), &CodeHighlighter::set_function_color);
+ ClassDB::bind_method(D_METHOD("get_function_color"), &CodeHighlighter::get_function_color);
+
+ ClassDB::bind_method(D_METHOD("set_number_color", "color"), &CodeHighlighter::set_number_color);
+ ClassDB::bind_method(D_METHOD("get_number_color"), &CodeHighlighter::get_number_color);
+
+ ClassDB::bind_method(D_METHOD("set_symbol_color", "color"), &CodeHighlighter::set_symbol_color);
+ ClassDB::bind_method(D_METHOD("get_symbol_color"), &CodeHighlighter::get_symbol_color);
+
+ ClassDB::bind_method(D_METHOD("set_member_variable_color", "color"), &CodeHighlighter::set_member_variable_color);
+ ClassDB::bind_method(D_METHOD("get_member_variable_color"), &CodeHighlighter::get_member_variable_color);
+
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "number_color"), "set_number_color", "get_number_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "symbol_color"), "set_symbol_color", "get_symbol_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "function_color"), "set_function_color", "get_function_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "member_variable_color"), "set_member_variable_color", "get_member_variable_color");
+
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "keyword_colors"), "set_keyword_colors", "get_keyword_colors");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "member_keyword_colors"), "set_member_keyword_colors", "get_member_keyword_colors");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "color_regions"), "set_color_regions", "get_color_regions");
+}
+
+void CodeHighlighter::set_number_color(Color p_color) {
+ number_color = p_color;
+ clear_highlighting_cache();
+}
+
+Color CodeHighlighter::get_number_color() const {
+ return number_color;
+}
+
+void CodeHighlighter::set_symbol_color(Color p_color) {
+ symbol_color = p_color;
+ clear_highlighting_cache();
+}
+
+Color CodeHighlighter::get_symbol_color() const {
+ return symbol_color;
+}
+
+void CodeHighlighter::set_function_color(Color p_color) {
+ function_color = p_color;
+ clear_highlighting_cache();
+}
+
+Color CodeHighlighter::get_function_color() const {
+ return function_color;
+}
+
+void CodeHighlighter::set_member_variable_color(Color p_color) {
+ member_color = p_color;
+ clear_highlighting_cache();
+}
+
+Color CodeHighlighter::get_member_variable_color() const {
+ return member_color;
+}
diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h
new file mode 100644
index 0000000000..720227a256
--- /dev/null
+++ b/scene/resources/syntax_highlighter.h
@@ -0,0 +1,140 @@
+/*************************************************************************/
+/* syntax_highlighter.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SYNTAX_HIGHLIGHTER_H
+#define SYNTAX_HIGHLIGHTER_H
+
+#include "core/resource.h"
+
+class TextEdit;
+
+class SyntaxHighlighter : public Resource {
+ GDCLASS(SyntaxHighlighter, Resource)
+
+private:
+ Map<int, Dictionary> highlighting_cache;
+ void _lines_edited_from(int p_from_line, int p_to_line);
+
+protected:
+ ObjectID text_edit_instance_id; // For validity check
+ TextEdit *text_edit = nullptr;
+
+ static void _bind_methods();
+
+public:
+ Dictionary get_line_syntax_highlighting(int p_line);
+ virtual Dictionary _get_line_syntax_highlighting(int p_line) { return Dictionary(); }
+
+ void clear_highlighting_cache();
+ virtual void _clear_highlighting_cache() {}
+
+ void update_cache();
+ virtual void _update_cache() {}
+
+ void set_text_edit(TextEdit *p_text_edit);
+ TextEdit *get_text_edit();
+
+ SyntaxHighlighter() {}
+ virtual ~SyntaxHighlighter() {}
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class CodeHighlighter : public SyntaxHighlighter {
+ GDCLASS(CodeHighlighter, SyntaxHighlighter)
+
+private:
+ struct ColorRegion {
+ Color color;
+ String start_key;
+ String end_key;
+ bool line_only;
+ };
+ Vector<ColorRegion> color_regions;
+ Map<int, int> color_region_cache;
+
+ Dictionary keywords;
+ Dictionary member_keywords;
+
+ Color font_color;
+ Color member_color;
+ Color function_color;
+ Color symbol_color;
+ Color number_color;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual Dictionary _get_line_syntax_highlighting(int p_line) override;
+
+ virtual void _clear_highlighting_cache() override;
+ virtual void _update_cache() override;
+
+ void add_keyword_color(const String &p_keyword, const Color &p_color);
+ void remove_keyword_color(const String &p_keyword);
+ bool has_keyword_color(const String &p_keyword) const;
+ Color get_keyword_color(const String &p_keyword) const;
+
+ void set_keyword_colors(const Dictionary p_keywords);
+ void clear_keyword_colors();
+ Dictionary get_keyword_colors() const;
+
+ void add_member_keyword_color(const String &p_member_keyword, const Color &p_color);
+ void remove_member_keyword_color(const String &p_member_keyword);
+ bool has_member_keyword_color(const String &p_member_keyword) const;
+ Color get_member_keyword_color(const String &p_member_keyword) const;
+
+ void set_member_keyword_colors(const Dictionary &p_color_regions);
+ void clear_member_keyword_colors();
+ Dictionary get_member_keyword_colors() const;
+
+ void add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only = false);
+ void remove_color_region(const String &p_start_key);
+ bool has_color_region(const String &p_start_key) const;
+
+ void set_color_regions(const Dictionary &p_member_keyword);
+ void clear_color_regions();
+ Dictionary get_color_regions() const;
+
+ void set_number_color(Color p_color);
+ Color get_number_color() const;
+
+ void set_symbol_color(Color p_color);
+ Color get_symbol_color() const;
+
+ void set_function_color(Color p_color);
+ Color get_function_color() const;
+
+ void set_member_variable_color(Color p_color);
+ Color get_member_variable_color() const;
+};
+
+#endif
diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp
index af55d2dde3..e3bd5ce0ae 100644
--- a/scene/resources/text_file.cpp
+++ b/scene/resources/text_file.cpp
@@ -49,8 +49,7 @@ void TextFile::reload_from_file() {
}
Error TextFile::load_text(const String &p_path) {
-
- PoolVector<uint8_t> sourcef;
+ Vector<uint8_t> sourcef;
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -58,15 +57,15 @@ Error TextFile::load_text(const String &p_path) {
int len = f->get_len();
sourcef.resize(len + 1);
- PoolVector<uint8_t>::Write w = sourcef.write();
- int r = f->get_buffer(w.ptr(), len);
+ uint8_t *w = sourcef.ptrw();
+ int r = f->get_buffer(w, len);
f->close();
memdelete(f);
ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
w[len] = 0;
String s;
- ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w.ptr()), ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
+ ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w), ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
text = s;
path = p_path;
return OK;
diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h
index 666c088d04..fa812b1e67 100644
--- a/scene/resources/text_file.h
+++ b/scene/resources/text_file.h
@@ -35,7 +35,6 @@
#include "core/io/resource_saver.h"
class TextFile : public Resource {
-
GDCLASS(TextFile, Resource);
private:
@@ -46,7 +45,7 @@ public:
virtual bool has_text() const;
virtual String get_text() const;
virtual void set_text(const String &p_code);
- virtual void reload_from_file();
+ virtual void reload_from_file() override;
void set_file_path(const String &p_path) { path = p_path; }
Error load_text(const String &p_path);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 4d23f0eb41..39237e1a33 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -38,82 +38,68 @@
#include "scene/resources/bit_map.h"
#include "servers/camera/camera_feed.h"
-Size2 Texture::get_size() const {
-
+Size2 Texture2D::get_size() const {
return Size2(get_width(), get_height());
}
-bool Texture::is_pixel_opaque(int p_x, int p_y) const {
+bool Texture2D::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void Texture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
-bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
-
+bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
r_rect = p_rect;
r_src_rect = p_src_rect;
return true;
}
-void Texture::_bind_methods() {
+void Texture2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height);
+ ClassDB::bind_method(D_METHOD("get_size"), &Texture2D::get_size);
+ ClassDB::bind_method(D_METHOD("has_alpha"), &Texture2D::has_alpha);
+ ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT));
+ ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT));
+ ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("get_data"), &Texture2D::get_data);
- ClassDB::bind_method(D_METHOD("get_width"), &Texture::get_width);
- ClassDB::bind_method(D_METHOD("get_height"), &Texture::get_height);
- ClassDB::bind_method(D_METHOD("get_size"), &Texture::get_size);
- ClassDB::bind_method(D_METHOD("has_alpha"), &Texture::has_alpha);
- ClassDB::bind_method(D_METHOD("set_flags", "flags"), &Texture::set_flags);
- ClassDB::bind_method(D_METHOD("get_flags"), &Texture::get_flags);
- ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose", "normal_map"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_data"), &Texture::get_data);
-
- ADD_GROUP("Flags", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic Linear,Convert to Linear,Mirrored Repeat,Video Surface"), "set_flags", "get_flags");
ADD_GROUP("", "");
-
- BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
- BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
- BIND_ENUM_CONSTANT(FLAG_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_FILTER);
- BIND_ENUM_CONSTANT(FLAG_ANISOTROPIC_FILTER);
- BIND_ENUM_CONSTANT(FLAG_CONVERT_TO_LINEAR);
- BIND_ENUM_CONSTANT(FLAG_MIRRORED_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_VIDEO_SURFACE);
}
-Texture::Texture() {
+Texture2D::Texture2D() {
}
/////////////////////
void ImageTexture::reload_from_file() {
-
String path = ResourceLoader::path_remap(get_path());
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
- uint32_t flags = get_flags();
Ref<Image> img;
img.instance();
if (ImageLoader::load_image(path, img) == OK) {
- create_from_image(img, flags);
+ create_from_image(img);
} else {
Resource::reload_from_file();
_change_notify();
@@ -122,55 +108,42 @@ void ImageTexture::reload_from_file() {
}
bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
-
- if (p_name == "image")
- create_from_image(p_value, flags);
- else if (p_name == "flags")
- if (w * h == 0)
- flags = p_value;
- else
- set_flags(p_value);
- else if (p_name == "size") {
+ if (p_name == "image") {
+ create_from_image(p_value);
+ } else if (p_name == "size") {
Size2 s = p_value;
w = s.width;
h = s.height;
- VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0);
- } else if (p_name == "_data") {
- _set_data(p_value);
- } else
+ RenderingServer::get_singleton()->texture_set_size_override(texture, w, h);
+ } else {
return false;
+ }
return true;
}
bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (p_name == "image_data") {
-
- } else if (p_name == "image")
+ if (p_name == "image") {
r_ret = get_data();
- else if (p_name == "flags")
- r_ret = flags;
- else if (p_name == "size")
+ } else if (p_name == "size") {
r_ret = Size2(w, h);
- else
+ } else {
return false;
+ }
return true;
}
void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
}
void ImageTexture::_reload_hook(const RID &p_hook) {
-
String path = get_path();
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
Ref<Image> img;
img.instance();
@@ -178,79 +151,48 @@ void ImageTexture::_reload_hook(const RID &p_hook) {
ERR_FAIL_COND_MSG(err != OK, "Cannot load image from path '" + path + "'.");
- VisualServer::get_singleton()->texture_set_data(texture, img);
-
- _change_notify();
- emit_changed();
-}
-
-void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
+ RID new_texture = RenderingServer::get_singleton()->texture_2d_create(img);
+ RenderingServer::get_singleton()->texture_replace(texture, new_texture);
- flags = p_flags;
- VisualServer::get_singleton()->texture_allocate(texture, p_width, p_height, 0, p_format, VS::TEXTURE_TYPE_2D, p_flags);
- format = p_format;
- w = p_width;
- h = p_height;
_change_notify();
emit_changed();
}
-void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags) {
+void ImageTexture::create_from_image(const Ref<Image> &p_image) {
ERR_FAIL_COND(p_image.is_null());
- flags = p_flags;
w = p_image->get_width();
h = p_image->get_height();
format = p_image->get_format();
+ mipmaps = p_image->has_mipmaps();
- VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_flags);
- VisualServer::get_singleton()->texture_set_data(texture, p_image);
+ if (texture.is_null()) {
+ texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
+ } else {
+ RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
+ RenderingServer::get_singleton()->texture_replace(texture, new_texture);
+ }
_change_notify();
emit_changed();
image_stored = true;
}
-void ImageTexture::set_flags(uint32_t p_flags) {
-
- if (flags == p_flags)
- return;
-
- flags = p_flags;
- if (w == 0 || h == 0) {
- return; //uninitialized, do not set to texture
- }
- VisualServer::get_singleton()->texture_set_flags(texture, p_flags);
- _change_notify("flags");
- emit_changed();
-}
-
-uint32_t ImageTexture::get_flags() const {
-
- return ImageTexture::flags;
-}
-
Image::Format ImageTexture::get_format() const {
-
return format;
}
-#ifndef DISABLE_DEPRECATED
-Error ImageTexture::load(const String &p_path) {
-
- WARN_DEPRECATED;
- Ref<Image> img;
- img.instance();
- Error err = img->load(p_path);
- if (err == OK) {
- create_from_image(img);
- }
- return err;
-}
-#endif
-void ImageTexture::set_data(const Ref<Image> &p_image) {
+void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) {
ERR_FAIL_COND(p_image.is_null());
+ ERR_FAIL_COND(texture.is_null());
+ ERR_FAIL_COND(p_image->get_width() != w || p_image->get_height() != h);
+ ERR_FAIL_COND(p_image->get_format() != format);
+ ERR_FAIL_COND(mipmaps != p_image->has_mipmaps());
- VisualServer::get_singleton()->texture_set_data(texture, p_image);
+ if (p_immediate) {
+ RenderingServer::get_singleton()->texture_2d_update_immediate(texture, p_image);
+ } else {
+ RenderingServer::get_singleton()->texture_2d_update(texture, p_image);
+ }
_change_notify();
emit_changed();
@@ -260,63 +202,65 @@ void ImageTexture::set_data(const Ref<Image> &p_image) {
}
void ImageTexture::_resource_path_changed() {
-
String path = get_path();
}
Ref<Image> ImageTexture::get_data() const {
-
if (image_stored) {
- return VisualServer::get_singleton()->texture_get_data(texture);
+ return RenderingServer::get_singleton()->texture_2d_get(texture);
} else {
return Ref<Image>();
}
}
int ImageTexture::get_width() const {
-
return w;
}
int ImageTexture::get_height() const {
-
return h;
}
RID ImageTexture::get_rid() const {
-
+ if (texture.is_null()) {
+ //we are in trouble, create something temporary
+ texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
+ }
return texture;
}
bool ImageTexture::has_alpha() const {
-
return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8);
}
-void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
-
- if ((w | h) == 0)
+void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
- if ((w | h) == 0)
+void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
- if ((w | h) == 0)
+void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
-
if (!alpha_cache.is_valid()) {
Ref<Image> img = get_data();
if (img.is_valid()) {
@@ -331,7 +275,6 @@ bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
}
if (alpha_cache.is_valid()) {
-
int aw = int(alpha_cache->get_size().width);
int ah = int(alpha_cache->get_size().height);
if (aw == 0 || ah == 0) {
@@ -351,451 +294,404 @@ bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
}
void ImageTexture::set_size_override(const Size2 &p_size) {
-
Size2 s = p_size;
- if (s.x != 0)
+ if (s.x != 0) {
w = s.x;
- if (s.y != 0)
+ }
+ if (s.y != 0) {
h = s.y;
- VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0);
+ }
+ RenderingServer::get_singleton()->texture_set_size_override(texture, w, h);
}
void ImageTexture::set_path(const String &p_path, bool p_take_over) {
-
if (texture.is_valid()) {
- VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
Resource::set_path(p_path, p_take_over);
}
-void ImageTexture::set_storage(Storage p_storage) {
-
- storage = p_storage;
-}
-
-ImageTexture::Storage ImageTexture::get_storage() const {
-
- return storage;
-}
-
-void ImageTexture::set_lossy_storage_quality(float p_lossy_storage_quality) {
-
- lossy_storage_quality = p_lossy_storage_quality;
-}
-
-float ImageTexture::get_lossy_storage_quality() const {
-
- return lossy_storage_quality;
-}
-
-void ImageTexture::_set_data(Dictionary p_data) {
-
- Ref<Image> img = p_data["image"];
- ERR_FAIL_COND(!img.is_valid());
- uint32_t flags = p_data["flags"];
-
- create_from_image(img, flags);
-
- set_storage(Storage(p_data["storage"].operator int()));
- set_lossy_storage_quality(p_data["lossy_quality"]);
-
- set_size_override(p_data["size"]);
-};
-
void ImageTexture::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("create", "width", "height", "format", "flags"), &ImageTexture::create, DEFVAL(FLAGS_DEFAULT));
- ClassDB::bind_method(D_METHOD("create_from_image", "image", "flags"), &ImageTexture::create_from_image, DEFVAL(FLAGS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
-#ifndef DISABLE_DEPRECATED
- ClassDB::bind_method(D_METHOD("load", "path"), &ImageTexture::load);
-#endif
- ClassDB::bind_method(D_METHOD("set_data", "image"), &ImageTexture::set_data);
- ClassDB::bind_method(D_METHOD("set_storage", "mode"), &ImageTexture::set_storage);
- ClassDB::bind_method(D_METHOD("get_storage"), &ImageTexture::get_storage);
- ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &ImageTexture::set_lossy_storage_quality);
- ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &ImageTexture::get_lossy_storage_quality);
+ ClassDB::bind_method(D_METHOD("update", "image", "immediate"), &ImageTexture::update, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "storage", PROPERTY_HINT_ENUM, "Uncompressed,Compress Lossy,Compress Lossless"), "set_storage", "get_storage");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_quality", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_lossy_storage_quality", "get_lossy_storage_quality");
-
- BIND_ENUM_CONSTANT(STORAGE_RAW);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSY);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSLESS);
}
ImageTexture::ImageTexture() {
-
w = h = 0;
- flags = FLAGS_DEFAULT;
- texture = VisualServer::get_singleton()->texture_create();
- storage = STORAGE_RAW;
- lossy_storage_quality = 0.7;
image_stored = false;
+ mipmaps = false;
format = Image::FORMAT_L8;
}
ImageTexture::~ImageTexture() {
-
- VisualServer::get_singleton()->free(texture);
-}
-
-//////////////////////////////////////////
-
-void StreamTexture::set_path(const String &p_path, bool p_take_over) {
-
if (texture.is_valid()) {
- VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ RenderingServer::get_singleton()->free(texture);
}
-
- Resource::set_path(p_path, p_take_over);
-}
-
-void StreamTexture::_requested_3d(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
- ERR_FAIL_COND(!request_3d_callback);
- request_3d_callback(stex);
-}
-
-void StreamTexture::_requested_srgb(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
- ERR_FAIL_COND(!request_srgb_callback);
- request_srgb_callback(stex);
-}
-
-void StreamTexture::_requested_normal(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
- ERR_FAIL_COND(!request_normal_callback);
- request_normal_callback(stex);
-}
-
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL;
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_srgb_callback = NULL;
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL;
-
-uint32_t StreamTexture::get_flags() const {
-
- return flags;
-}
-Image::Format StreamTexture::get_format() const {
-
- return format;
}
-Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit) {
-
- alpha_cache.unref();
-
- ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
-
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
-
- uint8_t header[4];
- f->get_buffer(header, 4);
- if (header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T') {
- memdelete(f);
- ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT);
- }
-
- tw = f->get_16();
- tw_custom = f->get_16();
- th = f->get_16();
- th_custom = f->get_16();
-
- flags = f->get_32(); //texture flags!
- uint32_t df = f->get_32(); //data format
-
- /*
- print_line("width: " + itos(tw));
- print_line("height: " + itos(th));
- print_line("flags: " + itos(flags));
- print_line("df: " + itos(df));
- */
-#ifdef TOOLS_ENABLED
-
- if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) {
- //print_line("request detect 3D at " + p_path);
- VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
- } else {
- //print_line("not requesting detect 3D at " + p_path);
- VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL);
- }
-
- if (request_srgb_callback && df & FORMAT_BIT_DETECT_SRGB) {
- //print_line("request detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_srgb_callback(texture, _requested_srgb, this);
- } else {
- //print_line("not requesting detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL);
- }
+//////////////////////////////////////////
- if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) {
- //print_line("request detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
- } else {
- //print_line("not requesting detect normal at " + p_path);
- VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
- }
-#endif
- if (!(df & FORMAT_BIT_STREAM)) {
- p_size_limit = 0;
- }
+Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit) {
+ uint32_t data_format = f->get_32();
+ uint32_t w = f->get_16();
+ uint32_t h = f->get_16();
+ uint32_t mipmaps = f->get_32();
+ Image::Format format = Image::Format(f->get_32());
- if (df & FORMAT_BIT_LOSSLESS || df & FORMAT_BIT_LOSSY) {
+ if (data_format == DATA_FORMAT_LOSSLESS || data_format == DATA_FORMAT_LOSSY || data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
//look for a PNG or WEBP file inside
- int sw = tw;
- int sh = th;
-
- uint32_t mipmaps = f->get_32();
- uint32_t size = f->get_32();
-
- //print_line("mipmaps: " + itos(mipmaps));
-
- while (mipmaps > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) {
-
- f->seek(f->get_position() + size);
- mipmaps = f->get_32();
- size = f->get_32();
-
- sw = MAX(sw >> 1, 1);
- sh = MAX(sh >> 1, 1);
- mipmaps--;
- }
+ int sw = w;
+ int sh = h;
//mipmaps need to be read independently, they will be later combined
- Vector<Ref<Image> > mipmap_images;
+ Vector<Ref<Image>> mipmap_images;
int total_size = 0;
- for (uint32_t i = 0; i < mipmaps; i++) {
+ bool first = true;
+
+ for (uint32_t i = 0; i < mipmaps + 1; i++) {
+ uint32_t size = f->get_32();
- if (i) {
- size = f->get_32();
+ if (p_size_limit > 0 && i < (mipmaps - 1) && (sw > p_size_limit || sh > p_size_limit)) {
+ //can't load this due to size limit
+ sw = MAX(sw >> 1, 1);
+ sh = MAX(sh >> 1, 1);
+ f->seek(f->get_position() + size);
+ continue;
}
- PoolVector<uint8_t> pv;
+ Vector<uint8_t> pv;
pv.resize(size);
{
- PoolVector<uint8_t>::Write w = pv.write();
- f->get_buffer(w.ptr(), size);
+ uint8_t *wr = pv.ptrw();
+ f->get_buffer(wr, size);
}
Ref<Image> img;
- if (df & FORMAT_BIT_LOSSLESS) {
+ if (data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
+ img = Image::basis_universal_unpacker(pv);
+ } else if (data_format == DATA_FORMAT_LOSSLESS) {
img = Image::lossless_unpacker(pv);
} else {
img = Image::lossy_unpacker(pv);
}
if (img.is_null() || img->empty()) {
- memdelete(f);
- ERR_FAIL_COND_V(img.is_null() || img->empty(), ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(img.is_null() || img->empty(), Ref<Image>());
+ }
+
+ if (first) {
+ //format will actually be the format of the first image,
+ //as it may have changed on compression
+ format = img->get_format();
+ first = false;
+ } else if (img->get_format() != format) {
+ img->convert(format); //all needs to be the same format
}
total_size += img->get_data().size();
mipmap_images.push_back(img);
+
+ sw = MAX(sw >> 1, 1);
+ sh = MAX(sh >> 1, 1);
}
//print_line("mipmap read total: " + itos(mipmap_images.size()));
- memdelete(f); //no longer needed
+ Ref<Image> image;
+ image.instance();
if (mipmap_images.size() == 1) {
-
+ //only one image (which will most likely be the case anyway for this format)
image = mipmap_images[0];
- return OK;
+ return image;
} else {
- PoolVector<uint8_t> img_data;
+ //rarer use case, but needs to be supported
+ Vector<uint8_t> img_data;
img_data.resize(total_size);
{
- PoolVector<uint8_t>::Write w = img_data.write();
+ uint8_t *wr = img_data.ptrw();
int ofs = 0;
for (int i = 0; i < mipmap_images.size(); i++) {
-
- PoolVector<uint8_t> id = mipmap_images[i]->get_data();
+ Vector<uint8_t> id = mipmap_images[i]->get_data();
int len = id.size();
- PoolVector<uint8_t>::Read r = id.read();
- copymem(&w[ofs], r.ptr(), len);
+ const uint8_t *r = id.ptr();
+ copymem(&wr[ofs], r, len);
ofs += len;
}
}
- image->create(sw, sh, true, mipmap_images[0]->get_format(), img_data);
- return OK;
+ image->create(w, h, true, mipmap_images[0]->get_format(), img_data);
+ return image;
}
- } else {
+ } else if (data_format == DATA_FORMAT_IMAGE) {
+ int size = Image::get_image_data_size(w, h, format, mipmaps ? true : false);
- //look for regular format
- Image::Format format = (Image::Format)(df & FORMAT_MASK_IMAGE_FORMAT);
- bool mipmaps = df & FORMAT_BIT_HAS_MIPMAPS;
+ for (uint32_t i = 0; i < mipmaps + 1; i++) {
+ int tw, th;
+ int ofs = Image::get_image_mipmap_offset_and_dimensions(w, h, format, i, tw, th);
- if (!mipmaps) {
- int size = Image::get_image_data_size(tw, th, format, false);
+ if (p_size_limit > 0 && i < mipmaps && (p_size_limit > tw || p_size_limit > th)) {
+ if (ofs) {
+ f->seek(f->get_position() + ofs);
+ }
+ continue; //oops, size limit enforced, go to next
+ }
- PoolVector<uint8_t> img_data;
- img_data.resize(size);
+ Vector<uint8_t> data;
+ data.resize(size - ofs);
{
- PoolVector<uint8_t>::Write w = img_data.write();
- f->get_buffer(w.ptr(), size);
+ uint8_t *wr = data.ptrw();
+ f->get_buffer(wr, data.size());
}
- memdelete(f);
+ Ref<Image> image;
+ image.instance();
- image->create(tw, th, false, format, img_data);
- return OK;
- } else {
+ image->create(tw, th, mipmaps - i ? true : false, format, data);
- int sw = tw;
- int sh = th;
+ return image;
+ }
+ }
- int mipmaps2 = Image::get_image_required_mipmaps(tw, th, format);
- int total_size = Image::get_image_data_size(tw, th, format, true);
- int idx = 0;
+ return Ref<Image>();
+}
- while (mipmaps2 > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) {
+void StreamTexture2D::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
- sw = MAX(sw >> 1, 1);
- sh = MAX(sh >> 1, 1);
- mipmaps2--;
- idx++;
- }
+ Resource::set_path(p_path, p_take_over);
+}
- int ofs = Image::get_image_mipmap_offset(tw, th, format, idx);
+void StreamTexture2D::_requested_3d(void *p_ud) {
+ StreamTexture2D *st = (StreamTexture2D *)p_ud;
+ Ref<StreamTexture2D> stex(st);
+ ERR_FAIL_COND(!request_3d_callback);
+ request_3d_callback(stex);
+}
- if (total_size - ofs <= 0) {
- memdelete(f);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- }
+void StreamTexture2D::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) {
+ StreamTexture2D *st = (StreamTexture2D *)p_ud;
+ Ref<StreamTexture2D> stex(st);
+ ERR_FAIL_COND(!request_roughness_callback);
+ request_roughness_callback(stex, p_normal_path, p_roughness_channel);
+}
- f->seek(f->get_position() + ofs);
+void StreamTexture2D::_requested_normal(void *p_ud) {
+ StreamTexture2D *st = (StreamTexture2D *)p_ud;
+ Ref<StreamTexture2D> stex(st);
+ ERR_FAIL_COND(!request_normal_callback);
+ request_normal_callback(stex);
+}
- PoolVector<uint8_t> img_data;
- img_data.resize(total_size - ofs);
+StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_3d_callback = nullptr;
+StreamTexture2D::TextureFormatRoughnessRequestCallback StreamTexture2D::request_roughness_callback = nullptr;
+StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_normal_callback = nullptr;
- {
- PoolVector<uint8_t>::Write w = img_data.write();
- int bytes = f->get_buffer(w.ptr(), total_size - ofs);
- //print_line("requested read: " + itos(total_size - ofs) + " but got: " + itos(bytes));
-
- memdelete(f);
-
- int expected = total_size - ofs;
- if (bytes < expected) {
- //this is a compatibility workaround for older format, which saved less mipmaps2. It is still recommended the image is reimported.
- zeromem(w.ptr() + bytes, (expected - bytes));
- } else if (bytes != expected) {
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- }
- }
+Image::Format StreamTexture2D::get_format() const {
+ return format;
+}
- image->create(sw, sh, true, format, img_data);
+Error StreamTexture2D::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
+ alpha_cache.unref();
- return OK;
- }
+ ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
+
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+
+ uint8_t header[4];
+ f->get_buffer(header, 4);
+ if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != '2') {
+ memdelete(f);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is corrupt (Bad header).");
}
- return ERR_BUG; //unreachable
-}
+ uint32_t version = f->get_32();
+
+ if (version > FORMAT_VERSION) {
+ memdelete(f);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ }
+ tw_custom = f->get_32();
+ th_custom = f->get_32();
+ uint32_t df = f->get_32(); //data format
+
+ //skip reserved
+ mipmap_limit = int(f->get_32());
+ //reserved
+ f->get_32();
+ f->get_32();
+ f->get_32();
+
+#ifdef TOOLS_ENABLED
+
+ r_request_3d = request_3d_callback && df & FORMAT_BIT_DETECT_3D;
+ r_request_roughness = request_roughness_callback && df & FORMAT_BIT_DETECT_ROUGNESS;
+ r_request_normal = request_normal_callback && df & FORMAT_BIT_DETECT_NORMAL;
+
+#else
+
+ r_request_3d = false;
+ r_request_roughness = false;
+ r_request_normal = false;
+
+#endif
+ if (!(df & FORMAT_BIT_STREAM)) {
+ p_size_limit = 0;
+ }
+
+ image = load_image_from_file(f, p_size_limit);
-Error StreamTexture::load(const String &p_path) {
+ memdelete(f);
+
+ if (image.is_null() || image->empty()) {
+ return ERR_CANT_OPEN;
+ }
+
+ return OK;
+}
- int lw, lh, lwc, lhc, lflags;
+Error StreamTexture2D::load(const String &p_path) {
+ int lw, lh, lwc, lhc;
Ref<Image> image;
image.instance();
- Error err = _load_data(p_path, lw, lh, lwc, lhc, lflags, image);
- if (err)
+
+ bool request_3d;
+ bool request_normal;
+ bool request_roughness;
+ int mipmap_limit;
+
+ Error err = _load_data(p_path, lw, lh, lwc, lhc, image, request_3d, request_normal, request_roughness, mipmap_limit);
+ if (err) {
return err;
+ }
- if (get_path() == String()) {
- //temporarily set path if no path set for resource, helps find errors
- VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_create(image);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_create(image);
}
- VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, image->get_format(), VS::TEXTURE_TYPE_2D, lflags);
- VS::get_singleton()->texture_set_data(texture, image);
if (lwc || lhc) {
- VS::get_singleton()->texture_set_size_override(texture, lwc, lhc, 0);
- } else {
+ RS::get_singleton()->texture_set_size_override(texture, lwc, lhc);
}
w = lwc ? lwc : lw;
h = lhc ? lhc : lh;
- flags = lflags;
path_to_file = p_path;
format = image->get_format();
+ if (get_path() == String()) {
+ //temporarily set path if no path set for resource, helps find errors
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+#ifdef TOOLS_ENABLED
+
+ if (request_3d) {
+ //print_line("request detect 3D at " + p_path);
+ RS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
+ } else {
+ //print_line("not requesting detect 3D at " + p_path);
+ RS::get_singleton()->texture_set_detect_3d_callback(texture, nullptr, nullptr);
+ }
+
+ if (request_roughness) {
+ //print_line("request detect srgb at " + p_path);
+ RS::get_singleton()->texture_set_detect_roughness_callback(texture, _requested_roughness, this);
+ } else {
+ //print_line("not requesting detect srgb at " + p_path);
+ RS::get_singleton()->texture_set_detect_roughness_callback(texture, nullptr, nullptr);
+ }
+
+ if (request_normal) {
+ //print_line("request detect srgb at " + p_path);
+ RS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
+ } else {
+ //print_line("not requesting detect normal at " + p_path);
+ RS::get_singleton()->texture_set_detect_normal_callback(texture, nullptr, nullptr);
+ }
+
+#endif
_change_notify();
emit_changed();
return OK;
}
-String StreamTexture::get_load_path() const {
+String StreamTexture2D::get_load_path() const {
return path_to_file;
}
-int StreamTexture::get_width() const {
-
+int StreamTexture2D::get_width() const {
return w;
}
-int StreamTexture::get_height() const {
+int StreamTexture2D::get_height() const {
return h;
}
-RID StreamTexture::get_rid() const {
+RID StreamTexture2D::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_2d_placeholder_create();
+ }
return texture;
}
-void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
-
- if ((w | h) == 0)
+void StreamTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
- if ((w | h) == 0)
+void StreamTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
- if ((w | h) == 0)
+void StreamTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
-bool StreamTexture::has_alpha() const {
-
+bool StreamTexture2D::has_alpha() const {
return false;
}
-Ref<Image> StreamTexture::get_data() const {
-
- return VS::get_singleton()->texture_get_data(texture);
+Ref<Image> StreamTexture2D::get_data() const {
+ if (texture.is_valid()) {
+ return RS::get_singleton()->texture_2d_get(texture);
+ } else {
+ return Ref<Image>();
+ }
}
-bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
-
+bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const {
if (!alpha_cache.is_valid()) {
Ref<Image> img = get_data();
if (img.is_valid()) {
@@ -811,7 +707,6 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
}
if (alpha_cache.is_valid()) {
-
int aw = int(alpha_cache->get_size().width);
int ah = int(alpha_cache->get_size().height);
if (aw == 0 || ah == 0) {
@@ -829,191 +724,468 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void StreamTexture::set_flags(uint32_t p_flags) {
- flags = p_flags;
- VS::get_singleton()->texture_set_flags(texture, flags);
- _change_notify("flags");
+
+void StreamTexture2D::reload_from_file() {
+ String path = get_path();
+ if (!path.is_resource_file()) {
+ return;
+ }
+
+ path = ResourceLoader::path_remap(path); //remap for translation
+ path = ResourceLoader::import_remap(path); //remap for import
+ if (!path.is_resource_file()) {
+ return;
+ }
+
+ load(path);
+}
+
+void StreamTexture2D::_validate_property(PropertyInfo &property) const {
+}
+
+void StreamTexture2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture2D::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture2D::get_load_path);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
+}
+
+StreamTexture2D::StreamTexture2D() {
+ format = Image::FORMAT_MAX;
+ w = 0;
+ h = 0;
+}
+
+StreamTexture2D::~StreamTexture2D() {
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
+}
+
+RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ Ref<StreamTexture2D> st;
+ st.instance();
+ Error err = st->load(p_path);
+ if (r_error) {
+ *r_error = err;
+ }
+ if (err != OK) {
+ return RES();
+ }
+
+ return st;
+}
+
+void ResourceFormatLoaderStreamTexture2D::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("stex");
+}
+
+bool ResourceFormatLoaderStreamTexture2D::handles_type(const String &p_type) const {
+ return p_type == "StreamTexture2D";
+}
+
+String ResourceFormatLoaderStreamTexture2D::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "stex") {
+ return "StreamTexture2D";
+ }
+ return "";
+}
+
+////////////////////////////////////
+
+TypedArray<Image> Texture3D::_get_data() const {
+ Vector<Ref<Image>> data = get_data();
+
+ TypedArray<Image> ret;
+ ret.resize(data.size());
+ for (int i = 0; i < data.size(); i++) {
+ ret[i] = data[i];
+ }
+ return ret;
+}
+
+void Texture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format);
+ ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height);
+ ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth);
+ ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture3D::has_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_data);
+}
+//////////////////////////////////////////
+
+Image::Format ImageTexture3D::get_format() const {
+ return format;
+}
+int ImageTexture3D::get_width() const {
+ return width;
+}
+int ImageTexture3D::get_height() const {
+ return height;
+}
+int ImageTexture3D::get_depth() const {
+ return depth;
+}
+bool ImageTexture3D::has_mipmaps() const {
+ return mipmaps;
+}
+
+Error ImageTexture3D::_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data) {
+ Vector<Ref<Image>> images;
+ images.resize(p_data.size());
+ for (int i = 0; i < images.size(); i++) {
+ images.write[i] = p_data[i];
+ }
+ return create(p_format, p_width, p_height, p_depth, p_mipmaps, images);
+}
+
+void ImageTexture3D::_update(const TypedArray<Image> &p_data) {
+ Vector<Ref<Image>> images;
+ images.resize(p_data.size());
+ for (int i = 0; i < images.size(); i++) {
+ images.write[i] = p_data[i];
+ }
+ return update(images);
+}
+
+Error ImageTexture3D::create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
+ RID tex = RenderingServer::get_singleton()->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
+ ERR_FAIL_COND_V(tex.is_null(), ERR_CANT_CREATE);
+
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_replace(texture, tex);
+ }
+
+ return OK;
+}
+
+void ImageTexture3D::update(const Vector<Ref<Image>> &p_data) {
+ ERR_FAIL_COND(!texture.is_valid());
+ RenderingServer::get_singleton()->texture_3d_update(texture, p_data);
+}
+
+Vector<Ref<Image>> ImageTexture3D::get_data() const {
+ ERR_FAIL_COND_V(!texture.is_valid(), Vector<Ref<Image>>());
+ return RS::get_singleton()->texture_3d_get(texture);
+}
+
+RID ImageTexture3D::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_3d_placeholder_create();
+ }
+ return texture;
+}
+void ImageTexture3D::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+ Resource::set_path(p_path, p_take_over);
+}
+
+void ImageTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create", "format", "width", "height", "depth", "use_mipmaps", "data"), &ImageTexture3D::_create);
+ ClassDB::bind_method(D_METHOD("update", "data"), &ImageTexture3D::_update);
+}
+
+ImageTexture3D::ImageTexture3D() {
+}
+
+ImageTexture3D::~ImageTexture3D() {
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
+}
+
+////////////////////////////////////////////
+
+void StreamTexture3D::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+ Resource::set_path(p_path, p_take_over);
+}
+
+Image::Format StreamTexture3D::get_format() const {
+ return format;
+}
+
+Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) {
+ FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+
+ uint8_t header[4];
+ f->get_buffer(header, 4);
+ ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L', ERR_FILE_UNRECOGNIZED);
+
+ //stored as stream textures (used for lossless and lossy compression)
+ uint32_t version = f->get_32();
+
+ if (version > FORMAT_VERSION) {
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ }
+
+ r_depth = f->get_32(); //depth
+ f->get_32(); //ignored (mode)
+ f->get_32(); // ignored (data format)
+
+ f->get_32(); //ignored
+ int mipmaps = f->get_32();
+ f->get_32(); //ignored
+ f->get_32(); //ignored
+
+ r_mipmaps = mipmaps != 0;
+
+ r_data.clear();
+
+ for (int i = 0; i < (r_depth + mipmaps); i++) {
+ Ref<Image> image = StreamTexture2D::load_image_from_file(f, 0);
+ ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN);
+ if (i == 0) {
+ r_format = image->get_format();
+ r_width = image->get_width();
+ r_height = image->get_height();
+ }
+ r_data.push_back(image);
+ }
+
+ return OK;
+}
+
+Error StreamTexture3D::load(const String &p_path) {
+ Vector<Ref<Image>> data;
+
+ int tw, th, td;
+ Image::Format tfmt;
+ bool tmm;
+
+ Error err = _load_data(p_path, data, tfmt, tw, th, td, tmm);
+ if (err) {
+ return err;
+ }
+
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data);
+ }
+
+ w = tw;
+ h = th;
+ d = td;
+ mipmaps = tmm;
+ format = tfmt;
+
+ path_to_file = p_path;
+
+ if (get_path() == String()) {
+ //temporarily set path if no path set for resource, helps find errors
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+ _change_notify();
emit_changed();
+ return OK;
+}
+
+String StreamTexture3D::get_load_path() const {
+ return path_to_file;
+}
+
+int StreamTexture3D::get_width() const {
+ return w;
}
-void StreamTexture::reload_from_file() {
+int StreamTexture3D::get_height() const {
+ return h;
+}
+int StreamTexture3D::get_depth() const {
+ return d;
+}
+
+bool StreamTexture3D::has_mipmaps() const {
+ return mipmaps;
+}
+
+RID StreamTexture3D::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_3d_placeholder_create();
+ }
+ return texture;
+}
+
+Vector<Ref<Image>> StreamTexture3D::get_data() const {
+ if (texture.is_valid()) {
+ return RS::get_singleton()->texture_3d_get(texture);
+ } else {
+ return Vector<Ref<Image>>();
+ }
+}
+
+void StreamTexture3D::reload_from_file() {
String path = get_path();
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
path = ResourceLoader::path_remap(path); //remap for translation
path = ResourceLoader::import_remap(path); //remap for import
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
load(path);
}
-void StreamTexture::_validate_property(PropertyInfo &property) const {
- if (property.name == "flags") {
- property.usage = PROPERTY_USAGE_NOEDITOR;
- }
+void StreamTexture3D::_validate_property(PropertyInfo &property) const {
}
-void StreamTexture::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture::load);
- ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture::get_load_path);
+void StreamTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture3D::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture3D::get_load_path);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
}
-StreamTexture::StreamTexture() {
-
+StreamTexture3D::StreamTexture3D() {
format = Image::FORMAT_MAX;
- flags = 0;
w = 0;
h = 0;
-
- texture = VS::get_singleton()->texture_create();
+ d = 0;
+ mipmaps = false;
}
-StreamTexture::~StreamTexture() {
-
- VS::get_singleton()->free(texture);
+StreamTexture3D::~StreamTexture3D() {
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
}
-RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error) {
+/////////////////////////////
- Ref<StreamTexture> st;
+RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ Ref<StreamTexture3D> st;
st.instance();
Error err = st->load(p_path);
- if (r_error)
+ if (r_error) {
*r_error = err;
- if (err != OK)
+ }
+ if (err != OK) {
return RES();
+ }
return st;
}
-void ResourceFormatLoaderStreamTexture::get_recognized_extensions(List<String> *p_extensions) const {
-
- p_extensions->push_back("stex");
+void ResourceFormatLoaderStreamTexture3D::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("stex3d");
}
-bool ResourceFormatLoaderStreamTexture::handles_type(const String &p_type) const {
- return p_type == "StreamTexture";
+
+bool ResourceFormatLoaderStreamTexture3D::handles_type(const String &p_type) const {
+ return p_type == "StreamTexture3D";
}
-String ResourceFormatLoaderStreamTexture::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "stex")
- return "StreamTexture";
+String ResourceFormatLoaderStreamTexture3D::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "stex3d") {
+ return "StreamTexture3D";
+ }
return "";
}
-//////////////////////////////////////////
+////////////////////////////////////////////
int AtlasTexture::get_width() const {
-
if (region.size.width == 0) {
- if (atlas.is_valid())
+ if (atlas.is_valid()) {
return atlas->get_width();
+ }
return 1;
} else {
return region.size.width + margin.size.width;
}
}
-int AtlasTexture::get_height() const {
+int AtlasTexture::get_height() const {
if (region.size.height == 0) {
- if (atlas.is_valid())
+ if (atlas.is_valid()) {
return atlas->get_height();
+ }
return 1;
} else {
return region.size.height + margin.size.height;
}
}
-RID AtlasTexture::get_rid() const {
- if (atlas.is_valid())
+RID AtlasTexture::get_rid() const {
+ if (atlas.is_valid()) {
return atlas->get_rid();
+ }
return RID();
}
bool AtlasTexture::has_alpha() const {
-
- if (atlas.is_valid())
+ if (atlas.is_valid()) {
return atlas->has_alpha();
+ }
return false;
}
-void AtlasTexture::set_flags(uint32_t p_flags) {
-
- if (atlas.is_valid())
- atlas->set_flags(p_flags);
-}
-
-uint32_t AtlasTexture::get_flags() const {
-
- if (atlas.is_valid())
- return atlas->get_flags();
-
- return 0;
-}
-
-void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) {
-
+void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) {
ERR_FAIL_COND(p_atlas == this);
- if (atlas == p_atlas)
+ if (atlas == p_atlas) {
return;
+ }
atlas = p_atlas;
emit_changed();
_change_notify("atlas");
}
-Ref<Texture> AtlasTexture::get_atlas() const {
+Ref<Texture2D> AtlasTexture::get_atlas() const {
return atlas;
}
void AtlasTexture::set_region(const Rect2 &p_region) {
-
- if (region == p_region)
+ if (region == p_region) {
return;
+ }
region = p_region;
emit_changed();
_change_notify("region");
}
Rect2 AtlasTexture::get_region() const {
-
return region;
}
void AtlasTexture::set_margin(const Rect2 &p_margin) {
-
- if (margin == p_margin)
+ if (margin == p_margin) {
return;
+ }
margin = p_margin;
emit_changed();
_change_notify("margin");
}
Rect2 AtlasTexture::get_margin() const {
-
return margin;
}
void AtlasTexture::set_filter_clip(const bool p_enable) {
-
filter_clip = p_enable;
emit_changed();
_change_notify("filter_clip");
}
bool AtlasTexture::has_filter_clip() const {
-
return filter_clip;
}
void AtlasTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_atlas", "atlas"), &AtlasTexture::set_atlas);
ClassDB::bind_method(D_METHOD("get_atlas"), &AtlasTexture::get_atlas);
@@ -1026,16 +1198,16 @@ void AtlasTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_filter_clip", "enable"), &AtlasTexture::set_filter_clip);
ClassDB::bind_method(D_METHOD("has_filter_clip"), &AtlasTexture::has_filter_clip);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_atlas", "get_atlas");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_atlas", "get_atlas");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region"), "set_region", "get_region");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_clip"), "set_filter_clip", "has_filter_clip");
}
-void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
-
- if (!atlas.is_valid())
+void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if (!atlas.is_valid()) {
return;
+ }
Rect2 rc = region;
@@ -1048,13 +1220,14 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
}
-void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
-
- if (!atlas.is_valid())
+void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if (!atlas.is_valid()) {
return;
+ }
Rect2 rc = region;
@@ -1070,26 +1243,29 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale);
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
}
-void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
//this might not necessarily work well if using a rect, needs to be fixed properly
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return;
+ }
Rect2 dr;
Rect2 src_c;
get_rect_region(p_rect, p_src_rect, dr, src_c);
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, filter_clip);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
}
bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
-
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return false;
+ }
Rect2 rc = region;
@@ -1101,8 +1277,9 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
src.position += (rc.position - margin.position);
Rect2 src_c = rc.clip(src);
- if (src_c.size == Size2())
+ if (src_c.size == Size2()) {
return false;
+ }
Vector2 ofs = (src_c.position - src.position);
if (scale.x < 0) {
@@ -1123,16 +1300,20 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
}
bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
-
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return true;
+ }
int x = p_x + region.position.x - margin.position.x;
int y = p_y + region.position.y - margin.position.y;
// margin edge may outside of atlas
- if (x < 0 || x >= atlas->get_width()) return false;
- if (y < 0 || y >= atlas->get_height()) return false;
+ if (x < 0 || x >= atlas->get_width()) {
+ return false;
+ }
+ if (y < 0 || y >= atlas->get_height()) {
+ return false;
+ }
return atlas->is_pixel_opaque(x, y);
}
@@ -1146,9 +1327,11 @@ AtlasTexture::AtlasTexture() {
int MeshTexture::get_width() const {
return size.width;
}
+
int MeshTexture::get_height() const {
return size.height;
}
+
RID MeshTexture::get_rid() const {
return RID();
}
@@ -1157,16 +1340,10 @@ bool MeshTexture::has_alpha() const {
return false;
}
-void MeshTexture::set_flags(uint32_t p_flags) {
-}
-
-uint32_t MeshTexture::get_flags() const {
- return 0;
-}
-
void MeshTexture::set_mesh(const Ref<Mesh> &p_mesh) {
mesh = p_mesh;
}
+
Ref<Mesh> MeshTexture::get_mesh() const {
return mesh;
}
@@ -1176,20 +1353,18 @@ void MeshTexture::set_image_size(const Size2 &p_size) {
}
Size2 MeshTexture::get_image_size() const {
-
return size;
}
-void MeshTexture::set_base_texture(const Ref<Texture> &p_texture) {
+void MeshTexture::set_base_texture(const Ref<Texture2D> &p_texture) {
base_texture = p_texture;
}
-Ref<Texture> MeshTexture::get_base_texture() const {
+Ref<Texture2D> MeshTexture::get_base_texture() const {
return base_texture;
}
-void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
-
+void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
}
@@ -1200,9 +1375,11 @@ void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_mo
SWAP(xform.elements[0][0], xform.elements[1][1]);
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+
+void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
}
@@ -1222,10 +1399,11 @@ void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile,
SWAP(xform.elements[0][0], xform.elements[1][1]);
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
}
@@ -1245,8 +1423,10 @@ void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const
SWAP(xform.elements[0][0], xform.elements[1][1]);
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
+
bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
r_rect = p_rect;
r_src_rect = p_src_rect;
@@ -1266,7 +1446,7 @@ void MeshTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_base_texture"), &MeshTexture::get_base_texture);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base_texture", "get_base_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base_texture", "get_base_texture");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "image_size", PROPERTY_HINT_RANGE, "0,16384,1"), "set_image_size", "get_image_size");
}
@@ -1276,45 +1456,28 @@ MeshTexture::MeshTexture() {
//////////////////////////////////////////
int LargeTexture::get_width() const {
-
return size.width;
}
-int LargeTexture::get_height() const {
+int LargeTexture::get_height() const {
return size.height;
}
-RID LargeTexture::get_rid() const {
+RID LargeTexture::get_rid() const {
return RID();
}
bool LargeTexture::has_alpha() const {
-
for (int i = 0; i < pieces.size(); i++) {
- if (pieces[i].texture->has_alpha())
+ if (pieces[i].texture->has_alpha()) {
return true;
+ }
}
return false;
}
-void LargeTexture::set_flags(uint32_t p_flags) {
-
- for (int i = 0; i < pieces.size(); i++) {
- pieces.write[i].texture->set_flags(p_flags);
- }
-}
-
-uint32_t LargeTexture::get_flags() const {
-
- if (pieces.size())
- return pieces[0].texture->get_flags();
-
- return 0;
-}
-
-int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture> &p_texture) {
-
+int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND_V(p_texture.is_null(), -1);
Piece p;
p.offset = p_offset;
@@ -1325,13 +1488,11 @@ int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture> &p_textur
}
void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) {
-
ERR_FAIL_INDEX(p_idx, pieces.size());
pieces.write[p_idx].offset = p_offset;
};
-void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) {
-
+void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(p_texture == this);
ERR_FAIL_COND(p_texture.is_null());
ERR_FAIL_INDEX(p_idx, pieces.size());
@@ -1339,17 +1500,15 @@ void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) {
};
void LargeTexture::set_size(const Size2 &p_size) {
-
size = p_size;
}
-void LargeTexture::clear() {
+void LargeTexture::clear() {
pieces.clear();
size = Size2i();
}
Array LargeTexture::_get_data() const {
-
Array arr;
for (int i = 0; i < pieces.size(); i++) {
arr.push_back(pieces[i].offset);
@@ -1358,8 +1517,8 @@ Array LargeTexture::_get_data() const {
arr.push_back(Size2(size));
return arr;
}
-void LargeTexture::_set_data(const Array &p_array) {
+void LargeTexture::_set_data(const Array &p_array) {
ERR_FAIL_COND(p_array.size() < 1);
ERR_FAIL_COND(!(p_array.size() & 1));
clear();
@@ -1370,24 +1529,22 @@ void LargeTexture::_set_data(const Array &p_array) {
}
int LargeTexture::get_piece_count() const {
-
return pieces.size();
}
-Vector2 LargeTexture::get_piece_offset(int p_idx) const {
+Vector2 LargeTexture::get_piece_offset(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, pieces.size(), Vector2());
return pieces[p_idx].offset;
}
-Ref<Texture> LargeTexture::get_piece_texture(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture>());
+Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture2D>());
return pieces[p_idx].texture;
}
-Ref<Image> LargeTexture::to_image() const {
+Ref<Image> LargeTexture::to_image() const {
Ref<Image> img = memnew(Image(this->get_width(), this->get_height(), false, Image::FORMAT_RGBA8));
for (int i = 0; i < pieces.size(); i++) {
-
Ref<Image> src_img = pieces[i].texture->get_data();
img->blit_rect(src_img, Rect2(0, 0, src_img->get_width(), src_img->get_height()), pieces[i].offset);
}
@@ -1396,7 +1553,6 @@ Ref<Image> LargeTexture::to_image() const {
}
void LargeTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_piece", "ofs", "texture"), &LargeTexture::add_piece);
ClassDB::bind_method(D_METHOD("set_piece_offset", "idx", "ofs"), &LargeTexture::set_piece_offset);
ClassDB::bind_method(D_METHOD("set_piece_texture", "idx", "texture"), &LargeTexture::set_piece_texture);
@@ -1413,59 +1569,56 @@ void LargeTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
-void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
-
+void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
- pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map);
+ pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
}
-void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
-
+void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
//tiling not supported for this
- if (size.x == 0 || size.y == 0)
+ if (size.x == 0 || size.y == 0) {
return;
+ }
Size2 scale = p_rect.size / size;
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
- pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map);
+ pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
}
-void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
//tiling not supported for this
- if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0)
+ if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0) {
return;
+ }
Size2 scale = p_rect.size / p_src_rect.size;
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
Rect2 rect(pieces[i].offset, pieces[i].texture->get_size());
- if (!p_src_rect.intersects(rect))
+ if (!p_src_rect.intersects(rect)) {
continue;
+ }
Rect2 local = p_src_rect.clip(rect);
Rect2 target = local;
target.size *= scale;
target.position = p_rect.position + (p_src_rect.position + rect.position) * scale;
local.position -= rect.position;
- pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, false);
+ pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat, false);
}
}
bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const {
-
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
- if (!pieces[i].texture.is_valid())
+ if (!pieces[i].texture.is_valid()) {
continue;
+ }
Rect2 rect(pieces[i].offset, pieces[i].texture->get_size());
if (rect.has_point(Point2(p_x, p_y))) {
@@ -1479,214 +1632,9 @@ bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const {
LargeTexture::LargeTexture() {
}
-///////////////////////////////////////////////
-
-void CubeMap::set_flags(uint32_t p_flags) {
-
- flags = p_flags;
- if (_is_valid())
- VS::get_singleton()->texture_set_flags(cubemap, flags);
-}
-
-uint32_t CubeMap::get_flags() const {
-
- return flags;
-}
-
-void CubeMap::set_side(Side p_side, const Ref<Image> &p_image) {
-
- ERR_FAIL_COND(p_image.is_null());
- ERR_FAIL_COND(p_image->empty());
- ERR_FAIL_INDEX(p_side, 6);
-
- if (!_is_valid()) {
- format = p_image->get_format();
- w = p_image->get_width();
- h = p_image->get_height();
- VS::get_singleton()->texture_allocate(cubemap, w, h, 0, p_image->get_format(), VS::TEXTURE_TYPE_CUBEMAP, flags);
- }
-
- VS::get_singleton()->texture_set_data(cubemap, p_image, VS::CubeMapSide(p_side));
- valid[p_side] = true;
-}
-
-Ref<Image> CubeMap::get_side(Side p_side) const {
-
- ERR_FAIL_INDEX_V(p_side, 6, Ref<Image>());
- if (!valid[p_side])
- return Ref<Image>();
- return VS::get_singleton()->texture_get_data(cubemap, VS::CubeMapSide(p_side));
-}
-
-Image::Format CubeMap::get_format() const {
-
- return format;
-}
-int CubeMap::get_width() const {
-
- return w;
-}
-int CubeMap::get_height() const {
-
- return h;
-}
-
-RID CubeMap::get_rid() const {
-
- return cubemap;
-}
-
-void CubeMap::set_storage(Storage p_storage) {
-
- storage = p_storage;
-}
-
-CubeMap::Storage CubeMap::get_storage() const {
-
- return storage;
-}
-
-void CubeMap::set_lossy_storage_quality(float p_lossy_storage_quality) {
-
- lossy_storage_quality = p_lossy_storage_quality;
-}
-
-float CubeMap::get_lossy_storage_quality() const {
-
- return lossy_storage_quality;
-}
-
-void CubeMap::set_path(const String &p_path, bool p_take_over) {
-
- if (cubemap.is_valid()) {
- VisualServer::get_singleton()->texture_set_path(cubemap, p_path);
- }
-
- Resource::set_path(p_path, p_take_over);
-}
-
-bool CubeMap::_set(const StringName &p_name, const Variant &p_value) {
-
- if (p_name == "side/left") {
- set_side(SIDE_LEFT, p_value);
- } else if (p_name == "side/right") {
- set_side(SIDE_RIGHT, p_value);
- } else if (p_name == "side/bottom") {
- set_side(SIDE_BOTTOM, p_value);
- } else if (p_name == "side/top") {
- set_side(SIDE_TOP, p_value);
- } else if (p_name == "side/front") {
- set_side(SIDE_FRONT, p_value);
- } else if (p_name == "side/back") {
- set_side(SIDE_BACK, p_value);
- } else if (p_name == "storage") {
- storage = Storage(p_value.operator int());
- } else if (p_name == "lossy_quality") {
- lossy_storage_quality = p_value;
- } else
- return false;
-
- return true;
-}
-
-bool CubeMap::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (p_name == "side/left") {
- r_ret = get_side(SIDE_LEFT);
- } else if (p_name == "side/right") {
- r_ret = get_side(SIDE_RIGHT);
- } else if (p_name == "side/bottom") {
- r_ret = get_side(SIDE_BOTTOM);
- } else if (p_name == "side/top") {
- r_ret = get_side(SIDE_TOP);
- } else if (p_name == "side/front") {
- r_ret = get_side(SIDE_FRONT);
- } else if (p_name == "side/back") {
- r_ret = get_side(SIDE_BACK);
- } else if (p_name == "storage") {
- r_ret = storage;
- } else if (p_name == "lossy_quality") {
- r_ret = lossy_storage_quality;
- } else
- return false;
-
- return true;
-}
-
-void CubeMap::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/left", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/right", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/bottom", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/top", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/front", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/back", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
-}
-
-void CubeMap::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("get_width"), &CubeMap::get_width);
- ClassDB::bind_method(D_METHOD("get_height"), &CubeMap::get_height);
- ClassDB::bind_method(D_METHOD("set_flags", "flags"), &CubeMap::set_flags);
- ClassDB::bind_method(D_METHOD("get_flags"), &CubeMap::get_flags);
- ClassDB::bind_method(D_METHOD("set_side", "side", "image"), &CubeMap::set_side);
- ClassDB::bind_method(D_METHOD("get_side", "side"), &CubeMap::get_side);
- ClassDB::bind_method(D_METHOD("set_storage", "mode"), &CubeMap::set_storage);
- ClassDB::bind_method(D_METHOD("get_storage"), &CubeMap::get_storage);
- ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &CubeMap::set_lossy_storage_quality);
- ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &CubeMap::get_lossy_storage_quality);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "storage_mode", PROPERTY_HINT_ENUM, "Raw,Lossy Compressed,Lossless Compressed"), "set_storage", "get_storage");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_storage_quality"), "set_lossy_storage_quality", "get_lossy_storage_quality");
-
- BIND_ENUM_CONSTANT(STORAGE_RAW);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSY);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSLESS);
-
- BIND_ENUM_CONSTANT(SIDE_LEFT);
- BIND_ENUM_CONSTANT(SIDE_RIGHT);
- BIND_ENUM_CONSTANT(SIDE_BOTTOM);
- BIND_ENUM_CONSTANT(SIDE_TOP);
- BIND_ENUM_CONSTANT(SIDE_FRONT);
- BIND_ENUM_CONSTANT(SIDE_BACK);
-
- BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
- BIND_ENUM_CONSTANT(FLAG_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_FILTER);
- BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
-}
-
-CubeMap::CubeMap() {
-
- w = h = 0;
- flags = FLAGS_DEFAULT;
- for (int i = 0; i < 6; i++)
- valid[i] = false;
- cubemap = VisualServer::get_singleton()->texture_create();
- storage = STORAGE_RAW;
- lossy_storage_quality = 0.7;
- format = Image::FORMAT_BPTC_RGBA;
-}
-
-CubeMap::~CubeMap() {
-
- VisualServer::get_singleton()->free(cubemap);
-}
-
-/* BIND_ENUM(CubeMapSize);
- BIND_ENUM_CONSTANT( FLAG_CUBEMAP );
- BIND_ENUM_CONSTANT( CUBEMAP_LEFT );
- BIND_ENUM_CONSTANT( CUBEMAP_RIGHT );
- BIND_ENUM_CONSTANT( CUBEMAP_BOTTOM );
- BIND_ENUM_CONSTANT( CUBEMAP_TOP );
- BIND_ENUM_CONSTANT( CUBEMAP_FRONT );
- BIND_ENUM_CONSTANT( CUBEMAP_BACK );
-*/
-///////////////////////////
+///////////////////
void CurveTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &CurveTexture::set_curve);
@@ -1699,14 +1647,12 @@ void CurveTexture::_bind_methods() {
}
void CurveTexture::set_width(int p_width) {
-
ERR_FAIL_COND(p_width < 32 || p_width > 4096);
_width = p_width;
_update();
}
int CurveTexture::get_width() const {
-
return _width;
}
@@ -1725,25 +1671,24 @@ void CurveTexture::ensure_default_setup(float p_min, float p_max) {
void CurveTexture::set_curve(Ref<Curve> p_curve) {
if (_curve != p_curve) {
if (_curve.is_valid()) {
- _curve->disconnect(CoreStringNames::get_singleton()->changed, this, "_update");
+ _curve->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveTexture::_update));
}
_curve = p_curve;
if (_curve.is_valid()) {
- _curve->connect(CoreStringNames::get_singleton()->changed, this, "_update");
+ _curve->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveTexture::_update));
}
_update();
}
}
void CurveTexture::_update() {
-
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(_width * sizeof(float));
// The array is locked in that scope
{
- PoolVector<uint8_t>::Write wd8 = data.write();
- float *wd = (float *)wd8.ptr();
+ uint8_t *wd8 = data.ptrw();
+ float *wd = (float *)wd8;
if (_curve.is_valid()) {
Curve &curve = **_curve;
@@ -1761,29 +1706,37 @@ void CurveTexture::_update() {
Ref<Image> image = memnew(Image(_width, 1, false, Image::FORMAT_RF, data));
- VS::get_singleton()->texture_allocate(_texture, _width, 1, 0, Image::FORMAT_RF, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
- VS::get_singleton()->texture_set_data(_texture, image);
+ if (_texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_create(image);
+ RS::get_singleton()->texture_replace(_texture, new_texture);
+ } else {
+ _texture = RS::get_singleton()->texture_2d_create(image);
+ }
emit_changed();
}
Ref<Curve> CurveTexture::get_curve() const {
-
return _curve;
}
RID CurveTexture::get_rid() const {
-
+ if (!_texture.is_valid()) {
+ _texture = RS::get_singleton()->texture_2d_placeholder_create();
+ }
return _texture;
}
CurveTexture::CurveTexture() {
_width = 2048;
- _texture = VS::get_singleton()->texture_create();
}
+
CurveTexture::~CurveTexture() {
- VS::get_singleton()->free(_texture);
+ if (_texture.is_valid()) {
+ RS::get_singleton()->free(_texture);
+ }
}
+
//////////////////
//setter and getter names for property serialization
@@ -1796,16 +1749,16 @@ GradientTexture::GradientTexture() {
update_pending = false;
width = 2048;
- texture = VS::get_singleton()->texture_create();
_queue_update();
}
GradientTexture::~GradientTexture() {
- VS::get_singleton()->free(texture);
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
}
void GradientTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_gradient", "gradient"), &GradientTexture::set_gradient);
ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture::get_gradient);
@@ -1818,14 +1771,15 @@ void GradientTexture::_bind_methods() {
}
void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {
- if (p_gradient == gradient)
+ if (p_gradient == gradient) {
return;
+ }
if (gradient.is_valid()) {
- gradient->disconnect(CoreStringNames::get_singleton()->changed, this, "_update");
+ gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture::_update));
}
gradient = p_gradient;
if (gradient.is_valid()) {
- gradient->connect(CoreStringNames::get_singleton()->changed, this, "_update");
+ gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture::_update));
}
_update();
emit_changed();
@@ -1836,29 +1790,28 @@ Ref<Gradient> GradientTexture::get_gradient() const {
}
void GradientTexture::_queue_update() {
-
- if (update_pending)
+ if (update_pending) {
return;
+ }
update_pending = true;
call_deferred("_update");
}
void GradientTexture::_update() {
-
update_pending = false;
- if (gradient.is_null())
+ if (gradient.is_null()) {
return;
+ }
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(width * 4);
{
- PoolVector<uint8_t>::Write wd8 = data.write();
+ uint8_t *wd8 = data.ptrw();
Gradient &g = **gradient;
for (int i = 0; i < width; i++) {
-
float ofs = float(i) / (width - 1);
Color color = g.get_color_at_offset(ofs);
@@ -1871,99 +1824,107 @@ void GradientTexture::_update() {
Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
- VS::get_singleton()->texture_allocate(texture, width, 1, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
- VS::get_singleton()->texture_set_data(texture, image);
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_create(image);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_create(image);
+ }
emit_changed();
}
void GradientTexture::set_width(int p_width) {
-
width = p_width;
_queue_update();
}
-int GradientTexture::get_width() const {
+int GradientTexture::get_width() const {
return width;
}
Ref<Image> GradientTexture::get_data() const {
- return VisualServer::get_singleton()->texture_get_data(texture);
+ if (!texture.is_valid()) {
+ return Ref<Image>();
+ }
+ return RenderingServer::get_singleton()->texture_2d_get(texture);
}
//////////////////////////////////////
void ProxyTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base);
ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base", "get_base");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base", "get_base");
}
-void ProxyTexture::set_base(const Ref<Texture> &p_texture) {
-
+void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(p_texture == this);
+
base = p_texture;
if (base.is_valid()) {
- VS::get_singleton()->texture_set_proxy(proxy, base->get_rid());
- } else {
- VS::get_singleton()->texture_set_proxy(proxy, RID());
+ if (proxy_ph.is_valid()) {
+ RS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
+ RS::get_singleton()->free(proxy_ph);
+ proxy_ph = RID();
+ } else if (proxy.is_valid()) {
+ RS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
+ } else {
+ proxy = RS::get_singleton()->texture_proxy_create(base->get_rid());
+ }
}
}
-Ref<Texture> ProxyTexture::get_base() const {
-
+Ref<Texture2D> ProxyTexture::get_base() const {
return base;
}
int ProxyTexture::get_width() const {
-
- if (base.is_valid())
+ if (base.is_valid()) {
return base->get_width();
+ }
return 1;
}
-int ProxyTexture::get_height() const {
- if (base.is_valid())
+int ProxyTexture::get_height() const {
+ if (base.is_valid()) {
return base->get_height();
+ }
return 1;
}
-RID ProxyTexture::get_rid() const {
+RID ProxyTexture::get_rid() const {
+ if (proxy.is_null()) {
+ proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
+ proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
+ }
return proxy;
}
bool ProxyTexture::has_alpha() const {
-
- if (base.is_valid())
+ if (base.is_valid()) {
return base->has_alpha();
+ }
return false;
}
-void ProxyTexture::set_flags(uint32_t p_flags) {
-}
-
-uint32_t ProxyTexture::get_flags() const {
-
- if (base.is_valid())
- return base->get_flags();
- return 0;
-}
-
ProxyTexture::ProxyTexture() {
-
- proxy = VS::get_singleton()->texture_create();
+ //proxy = RS::get_singleton()->texture_create();
}
ProxyTexture::~ProxyTexture() {
-
- VS::get_singleton()->free(proxy);
+ if (proxy_ph.is_valid()) {
+ RS::get_singleton()->free(proxy_ph);
+ }
+ if (proxy.is_valid()) {
+ RS::get_singleton()->free(proxy);
+ }
}
+
//////////////////////////////////////////////
void AnimatedTexture::_update_proxy() {
-
RWLockRead r(rw_lock);
float delta;
@@ -1987,15 +1948,20 @@ void AnimatedTexture::_update_proxy() {
}
int iter_max = frame_count;
- while (iter_max) {
+ while (iter_max && !pause) {
float frame_limit = limit + frames[current_frame].delay_sec;
if (time > frame_limit) {
current_frame++;
if (current_frame >= frame_count) {
- current_frame = 0;
+ if (oneshot) {
+ current_frame = frame_count - 1;
+ } else {
+ current_frame = 0;
+ }
}
time -= frame_limit;
+ _change_notify("current_frame");
} else {
break;
}
@@ -2003,7 +1969,7 @@ void AnimatedTexture::_update_proxy() {
}
if (frames[current_frame].texture.is_valid()) {
- VisualServer::get_singleton()->texture_set_proxy(proxy, frames[current_frame].texture->get_rid());
+ RenderingServer::get_singleton()->texture_proxy_update(proxy, frames[current_frame].texture->get_rid());
}
}
@@ -2014,12 +1980,42 @@ void AnimatedTexture::set_frames(int p_frames) {
frame_count = p_frames;
}
+
int AnimatedTexture::get_frames() const {
return frame_count;
}
-void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) {
+void AnimatedTexture::set_current_frame(int p_frame) {
+ ERR_FAIL_COND(p_frame < 0 || p_frame >= frame_count);
+
+ RWLockWrite r(rw_lock);
+
+ current_frame = p_frame;
+}
+
+int AnimatedTexture::get_current_frame() const {
+ return current_frame;
+}
+
+void AnimatedTexture::set_pause(bool p_pause) {
+ RWLockWrite r(rw_lock);
+ pause = p_pause;
+}
+
+bool AnimatedTexture::get_pause() const {
+ return pause;
+}
+
+void AnimatedTexture::set_oneshot(bool p_oneshot) {
+ RWLockWrite r(rw_lock);
+ oneshot = p_oneshot;
+}
+
+bool AnimatedTexture::get_oneshot() const {
+ return oneshot;
+}
+void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(p_texture == this);
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
@@ -2027,8 +2023,9 @@ void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_textu
frames[p_frame].texture = p_texture;
}
-Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
- ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>());
+
+Ref<Texture2D> AnimatedTexture::get_frame_texture(int p_frame) const {
+ ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture2D>());
RWLockRead r(rw_lock);
@@ -2042,6 +2039,7 @@ void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
frames[p_frame].delay_sec = p_delay_sec;
}
+
float AnimatedTexture::get_frame_delay(int p_frame) const {
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
@@ -2055,6 +2053,7 @@ void AnimatedTexture::set_fps(float p_fps) {
fps = p_fps;
}
+
float AnimatedTexture::get_fps() const {
return fps;
}
@@ -2068,6 +2067,7 @@ int AnimatedTexture::get_width() const {
return frames[current_frame].texture->get_width();
}
+
int AnimatedTexture::get_height() const {
RWLockRead r(rw_lock);
@@ -2077,12 +2077,12 @@ int AnimatedTexture::get_height() const {
return frames[current_frame].texture->get_height();
}
+
RID AnimatedTexture::get_rid() const {
return proxy;
}
bool AnimatedTexture::has_alpha() const {
-
RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
@@ -2093,7 +2093,6 @@ bool AnimatedTexture::has_alpha() const {
}
Ref<Image> AnimatedTexture::get_data() const {
-
RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
@@ -2104,7 +2103,6 @@ Ref<Image> AnimatedTexture::get_data() const {
}
bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
-
RWLockRead r(rw_lock);
if (frames[current_frame].texture.is_valid()) {
@@ -2113,21 +2111,7 @@ bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void AnimatedTexture::set_flags(uint32_t p_flags) {
-}
-uint32_t AnimatedTexture::get_flags() const {
-
- RWLockRead r(rw_lock);
-
- if (!frames[current_frame].texture.is_valid()) {
- return 0;
- }
-
- return frames[current_frame].texture->get_flags();
-}
-
void AnimatedTexture::_validate_property(PropertyInfo &property) const {
-
String prop = property.name;
if (prop.begins_with("frame_")) {
int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int();
@@ -2141,6 +2125,15 @@ void AnimatedTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames);
ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames);
+ ClassDB::bind_method(D_METHOD("set_current_frame", "frame"), &AnimatedTexture::set_current_frame);
+ ClassDB::bind_method(D_METHOD("get_current_frame"), &AnimatedTexture::get_current_frame);
+
+ ClassDB::bind_method(D_METHOD("set_pause", "pause"), &AnimatedTexture::set_pause);
+ ClassDB::bind_method(D_METHOD("get_pause"), &AnimatedTexture::get_pause);
+
+ ClassDB::bind_method(D_METHOD("set_oneshot", "oneshot"), &AnimatedTexture::set_oneshot);
+ ClassDB::bind_method(D_METHOD("get_oneshot"), &AnimatedTexture::get_oneshot);
+
ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps);
ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps);
@@ -2150,374 +2143,438 @@ void AnimatedTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frame_delay", "frame", "delay"), &AnimatedTexture::set_frame_delay);
ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay);
- ClassDB::bind_method(D_METHOD("_update_proxy"), &AnimatedTexture::_update_proxy);
-
ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_frame", PROPERTY_HINT_NONE, "", 0), "set_current_frame", "get_current_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pause"), "set_pause", "get_pause");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "oneshot"), "set_oneshot", "get_oneshot");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
for (int i = 0; i < MAX_FRAMES; i++) {
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i);
}
BIND_CONSTANT(MAX_FRAMES);
}
AnimatedTexture::AnimatedTexture() {
- proxy = VS::get_singleton()->texture_create();
- VisualServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
+ //proxy = RS::get_singleton()->texture_create();
+ proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
+ proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
+
+ RenderingServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
time = 0;
frame_count = 1;
fps = 4;
prev_ticks = 0;
current_frame = 0;
- VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
+ pause = false;
+ oneshot = false;
+ RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy));
#ifndef NO_THREADS
rw_lock = RWLock::create();
#else
- rw_lock = NULL;
+ rw_lock = nullptr;
#endif
}
AnimatedTexture::~AnimatedTexture() {
- VS::get_singleton()->free(proxy);
+ RS::get_singleton()->free(proxy);
+ RS::get_singleton()->free(proxy_ph);
if (rw_lock) {
memdelete(rw_lock);
}
}
-///////////////////////////////
-void TextureLayered::set_flags(uint32_t p_flags) {
- flags = p_flags;
+///////////////////////////////
- if (texture.is_valid()) {
- VS::get_singleton()->texture_set_flags(texture, flags);
- }
-}
+void TextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
+ ClassDB::bind_method(D_METHOD("get_layered_type"), &TextureLayered::get_layered_type);
+ ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
+ ClassDB::bind_method(D_METHOD("get_layers"), &TextureLayered::get_layers);
+ ClassDB::bind_method(D_METHOD("has_mipmaps"), &TextureLayered::has_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
-uint32_t TextureLayered::get_flags() const {
- return flags;
+ BIND_ENUM_CONSTANT(LAYERED_TYPE_2D_ARRAY);
+ BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP);
+ BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP_ARRAY);
}
-Image::Format TextureLayered::get_format() const {
+///////////////////////////////
+Image::Format ImageTextureLayered::get_format() const {
return format;
}
-uint32_t TextureLayered::get_width() const {
+int ImageTextureLayered::get_width() const {
return width;
}
-uint32_t TextureLayered::get_height() const {
+int ImageTextureLayered::get_height() const {
return height;
}
-uint32_t TextureLayered::get_depth() const {
- return depth;
+int ImageTextureLayered::get_layers() const {
+ return layers;
}
-void TextureLayered::_set_data(const Dictionary &p_data) {
- ERR_FAIL_COND(!p_data.has("width"));
- ERR_FAIL_COND(!p_data.has("height"));
- ERR_FAIL_COND(!p_data.has("depth"));
- ERR_FAIL_COND(!p_data.has("format"));
- ERR_FAIL_COND(!p_data.has("flags"));
- ERR_FAIL_COND(!p_data.has("layers"));
- int w = p_data["width"];
- int h = p_data["height"];
- int d = p_data["depth"];
- Image::Format format = Image::Format(int(p_data["format"]));
- int flags = p_data["flags"];
- Array layers = p_data["layers"];
- ERR_FAIL_COND(layers.size() != d);
-
- create(w, h, d, format, flags);
-
- for (int i = 0; i < layers.size(); i++) {
- Ref<Image> img = layers[i];
- ERR_CONTINUE(!img.is_valid());
- ERR_CONTINUE(img->get_format() != format);
- ERR_CONTINUE(img->get_width() != w);
- ERR_CONTINUE(img->get_height() != h);
- set_layer_data(img, i);
- }
-}
-
-Dictionary TextureLayered::_get_data() const {
- Dictionary d;
- d["width"] = width;
- d["height"] = height;
- d["depth"] = depth;
- d["flags"] = flags;
- d["format"] = format;
-
- Array layers;
- for (int i = 0; i < depth; i++) {
- layers.push_back(get_layer_data(i));
- }
- d["layers"] = layers;
- return d;
+bool ImageTextureLayered::has_mipmaps() const {
+ return mipmaps;
}
-void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags) {
- VS::get_singleton()->texture_allocate(texture, p_width, p_height, p_depth, p_format, is_3d ? VS::TEXTURE_TYPE_3D : VS::TEXTURE_TYPE_2D_ARRAY, p_flags);
+ImageTextureLayered::LayeredType ImageTextureLayered::get_layered_type() const {
+ return layered_type;
+}
- width = p_width;
- height = p_height;
- depth = p_depth;
- format = p_format;
- flags = p_flags;
+Error ImageTextureLayered::_create_from_images(const Array &p_images) {
+ Vector<Ref<Image>> images;
+ for (int i = 0; i < p_images.size(); i++) {
+ Ref<Image> img = p_images[i];
+ ERR_FAIL_COND_V(img.is_null(), ERR_INVALID_PARAMETER);
+ images.push_back(img);
+ }
+
+ return create_from_images(images);
}
-void TextureLayered::set_layer_data(const Ref<Image> &p_image, int p_layer) {
- ERR_FAIL_COND(!texture.is_valid());
- ERR_FAIL_COND(!p_image.is_valid());
- VS::get_singleton()->texture_set_data(texture, p_image, p_layer);
+Array ImageTextureLayered::_get_images() const {
+ Array images;
+ for (int i = 0; i < layers; i++) {
+ images.push_back(get_layer_data(i));
+ }
+ return images;
}
-Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
+Error ImageTextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
+ int new_layers = p_images.size();
+ ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER);
+ if (layered_type == LAYERED_TYPE_CUBEMAP) {
+ ERR_FAIL_COND_V_MSG(new_layers != 6, ERR_INVALID_PARAMETER,
+ "Cubemaps require exactly 6 layers");
+ } else if (layered_type == LAYERED_TYPE_CUBEMAP_ARRAY) {
+ ERR_FAIL_COND_V_MSG((new_layers % 6) != 0, ERR_INVALID_PARAMETER,
+ "Cubemap array layers must be a multiple of 6");
+ }
+
+ ERR_FAIL_COND_V(p_images[0].is_null() || p_images[0]->empty(), ERR_INVALID_PARAMETER);
+
+ Image::Format new_format = p_images[0]->get_format();
+ int new_width = p_images[0]->get_width();
+ int new_height = p_images[0]->get_height();
+ bool new_mipmaps = p_images[0]->has_mipmaps();
+
+ for (int i = 1; i < p_images.size(); i++) {
+ ERR_FAIL_COND_V_MSG(p_images[i]->get_format() != new_format, ERR_INVALID_PARAMETER,
+ "All images must share the same format");
+ ERR_FAIL_COND_V_MSG(p_images[i]->get_width() != new_width || p_images[i]->get_height() != new_height, ERR_INVALID_PARAMETER,
+ "All images must share the same dimensions");
+ ERR_FAIL_COND_V_MSG(p_images[i]->has_mipmaps() != new_mipmaps, ERR_INVALID_PARAMETER,
+ "All images must share the usage of mipmaps");
+ }
+
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_layered_create(p_images, RS::TextureLayeredType(layered_type));
+ ERR_FAIL_COND_V(!new_texture.is_valid(), ERR_CANT_CREATE);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_layered_create(p_images, RS::TextureLayeredType(layered_type));
+ ERR_FAIL_COND_V(!texture.is_valid(), ERR_CANT_CREATE);
+ }
+
+ format = new_format;
+ width = new_width;
+ height = new_height;
+ layers = new_layers;
+ mipmaps = new_mipmaps;
+ return OK;
+}
- ERR_FAIL_COND_V(!texture.is_valid(), Ref<Image>());
- return VS::get_singleton()->texture_get_data(texture, p_layer);
+void ImageTextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
+ ERR_FAIL_COND(texture.is_valid());
+ ERR_FAIL_COND(p_image.is_null());
+ ERR_FAIL_COND(p_image->get_format() != format);
+ ERR_FAIL_COND(p_image->get_width() != width || p_image->get_height() != height);
+ ERR_FAIL_INDEX(p_layer, layers);
+ ERR_FAIL_COND(p_image->has_mipmaps() != mipmaps);
+ RS::get_singleton()->texture_2d_update(texture, p_image, p_layer);
}
-void TextureLayered::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap) {
- ERR_FAIL_COND(!texture.is_valid());
- ERR_FAIL_COND(!p_image.is_valid());
- VS::get_singleton()->texture_set_data_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_z);
+Ref<Image> ImageTextureLayered::get_layer_data(int p_layer) const {
+ ERR_FAIL_INDEX_V(p_layer, layers, Ref<Image>());
+ return RS::get_singleton()->texture_2d_layer_get(texture, p_layer);
}
-RID TextureLayered::get_rid() const {
+RID ImageTextureLayered::get_rid() const {
+ if (texture.is_null()) {
+ texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
+ }
return texture;
}
-void TextureLayered::set_path(const String &p_path, bool p_take_over) {
+void ImageTextureLayered::set_path(const String &p_path, bool p_take_over) {
if (texture.is_valid()) {
- VS::get_singleton()->texture_set_path(texture, p_path);
+ RS::get_singleton()->texture_set_path(texture, p_path);
}
Resource::set_path(p_path, p_take_over);
}
-void TextureLayered::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextureLayered::set_flags);
- ClassDB::bind_method(D_METHOD("get_flags"), &TextureLayered::get_flags);
-
- ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
-
- ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
- ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
- ClassDB::bind_method(D_METHOD("get_depth"), &TextureLayered::get_depth);
-
- ClassDB::bind_method(D_METHOD("create", "width", "height", "depth", "format", "flags"), &TextureLayered::create, DEFVAL(FLAGS_DEFAULT));
- ClassDB::bind_method(D_METHOD("set_layer_data", "image", "layer"), &TextureLayered::set_layer_data);
- ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
- ClassDB::bind_method(D_METHOD("set_data_partial", "image", "x_offset", "y_offset", "layer", "mipmap"), &TextureLayered::set_data_partial, DEFVAL(0));
-
- ClassDB::bind_method(D_METHOD("_set_data", "data"), &TextureLayered::_set_data);
- ClassDB::bind_method(D_METHOD("_get_data"), &TextureLayered::_get_data);
+void ImageTextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create_from_images", "images"), &ImageTextureLayered::_create_from_images);
+ ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &ImageTextureLayered::update_layer);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags");
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+ ClassDB::bind_method(D_METHOD("_get_images"), &ImageTextureLayered::_get_images);
- BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
- BIND_ENUM_CONSTANT(FLAG_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_FILTER);
- BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images");
}
-TextureLayered::TextureLayered(bool p_3d) {
- is_3d = p_3d;
+ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) {
+ layered_type = p_layered_type;
format = Image::FORMAT_MAX;
- flags = FLAGS_DEFAULT;
width = 0;
height = 0;
- depth = 0;
-
- texture = VS::get_singleton()->texture_create();
+ layers = 0;
}
-TextureLayered::~TextureLayered() {
+ImageTextureLayered::~ImageTextureLayered() {
if (texture.is_valid()) {
- VS::get_singleton()->free(texture);
+ RS::get_singleton()->free(texture);
}
}
-RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error) {
+///////////////////////////////////////////
- if (r_error) {
- *r_error = ERR_CANT_OPEN;
+void StreamTextureLayered::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
- Ref<TextureLayered> lt;
- Ref<Texture3D> tex3d;
- Ref<TextureArray> texarr;
+ Resource::set_path(p_path, p_take_over);
+}
- if (p_path.ends_with("tex3d")) {
- tex3d.instance();
- lt = tex3d;
- } else if (p_path.ends_with("texarr")) {
- texarr.instance();
- lt = texarr;
- } else {
- ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture extension.");
- }
+Image::Format StreamTextureLayered::get_format() const {
+ return format;
+}
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");
+Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit) {
+ ERR_FAIL_COND_V(images.size() != 0, ERR_INVALID_PARAMETER);
- uint8_t header[5] = { 0, 0, 0, 0, 0 };
+ FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+
+ uint8_t header[4];
f->get_buffer(header, 4);
+ if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L') {
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture layered file is corrupt (Bad header).");
+ }
- if (header[0] == 'G' && header[1] == 'D' && header[2] == '3' && header[3] == 'T') {
- if (tex3d.is_null()) {
- f->close();
- memdelete(f);
- ERR_FAIL_COND_V(tex3d.is_null(), RES())
- }
- } else if (header[0] == 'G' && header[1] == 'D' && header[2] == 'A' && header[3] == 'T') {
- if (texarr.is_null()) {
- f->close();
- memdelete(f);
- ERR_FAIL_COND_V(texarr.is_null(), RES())
- }
- } else {
+ uint32_t version = f->get_32();
- f->close();
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture file format '" + String((const char *)header) + "'.");
+ if (version > FORMAT_VERSION) {
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
}
- int tw = f->get_32();
- int th = f->get_32();
- int td = f->get_32();
- int flags = f->get_32(); //texture flags!
- Image::Format format = Image::Format(f->get_32());
- uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
+ uint32_t layer_count = f->get_32(); //layer count
+ uint32_t type = f->get_32(); //layer count
+ ERR_FAIL_COND_V(type != layered_type, ERR_INVALID_DATA);
- lt->create(tw, th, td, format, flags);
+ uint32_t df = f->get_32(); //data format
+ mipmap_limit = int(f->get_32());
+ //reserved
+ f->get_32();
+ f->get_32();
+ f->get_32();
- for (int layer = 0; layer < td; layer++) {
+ if (!(df & FORMAT_BIT_STREAM)) {
+ p_size_limit = 0;
+ }
- Ref<Image> image;
- image.instance();
+ images.resize(layer_count);
- if (compression == COMPRESSION_LOSSLESS) {
- //look for a PNG file inside
+ for (uint32_t i = 0; i < layer_count; i++) {
+ Ref<Image> image = StreamTexture2D::load_image_from_file(f, p_size_limit);
+ ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN);
+ images.write[i] = image;
+ }
- int mipmaps = f->get_32();
- Vector<Ref<Image> > mipmap_images;
+ return OK;
+}
- for (int i = 0; i < mipmaps; i++) {
- uint32_t size = f->get_32();
+Error StreamTextureLayered::load(const String &p_path) {
+ Vector<Ref<Image>> images;
- PoolVector<uint8_t> pv;
- pv.resize(size);
- {
- PoolVector<uint8_t>::Write w = pv.write();
- f->get_buffer(w.ptr(), size);
- }
+ int mipmap_limit;
- Ref<Image> img = Image::lossless_unpacker(pv);
+ Error err = _load_data(p_path, images, mipmap_limit);
+ if (err) {
+ return err;
+ }
- if (img.is_null() || img->empty() || format != img->get_format()) {
- if (r_error) {
- *r_error = ERR_FILE_CORRUPT;
- }
- f->close();
- memdelete(f);
- ERR_FAIL_V(RES());
- }
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TextureLayeredType(layered_type));
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TextureLayeredType(layered_type));
+ }
- mipmap_images.push_back(img);
- }
+ w = images[0]->get_width();
+ h = images[0]->get_height();
+ mipmaps = images[0]->has_mipmaps();
+ format = images[0]->get_format();
+ layers = images.size();
- if (mipmap_images.size() == 1) {
+ path_to_file = p_path;
- image = mipmap_images[0];
+ if (get_path() == String()) {
+ //temporarily set path if no path set for resource, helps find errors
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
- } else {
- int total_size = Image::get_image_data_size(tw, th, format, true);
- PoolVector<uint8_t> img_data;
- img_data.resize(total_size);
-
- {
- PoolVector<uint8_t>::Write w = img_data.write();
-
- int ofs = 0;
- for (int i = 0; i < mipmap_images.size(); i++) {
-
- PoolVector<uint8_t> id = mipmap_images[i]->get_data();
- int len = id.size();
- PoolVector<uint8_t>::Read r = id.read();
- copymem(&w[ofs], r.ptr(), len);
- ofs += len;
- }
- }
+ _change_notify();
+ emit_changed();
+ return OK;
+}
- image->create(tw, th, true, format, img_data);
- if (image->empty()) {
- if (r_error) {
- *r_error = ERR_FILE_CORRUPT;
- }
- f->close();
- memdelete(f);
- ERR_FAIL_V(RES());
- }
- }
+String StreamTextureLayered::get_load_path() const {
+ return path_to_file;
+}
- } else {
+int StreamTextureLayered::get_width() const {
+ return w;
+}
- //look for regular format
- bool mipmaps = (flags & Texture::FLAG_MIPMAPS);
- int total_size = Image::get_image_data_size(tw, th, format, mipmaps);
+int StreamTextureLayered::get_height() const {
+ return h;
+}
- PoolVector<uint8_t> img_data;
- img_data.resize(total_size);
+int StreamTextureLayered::get_layers() const {
+ return layers;
+}
- {
- PoolVector<uint8_t>::Write w = img_data.write();
- int bytes = f->get_buffer(w.ptr(), total_size);
- if (bytes != total_size) {
- if (r_error) {
- *r_error = ERR_FILE_CORRUPT;
- }
- f->close();
- memdelete(f);
- ERR_FAIL_V(RES());
- }
- }
+bool StreamTextureLayered::has_mipmaps() const {
+ return mipmaps;
+}
- image->create(tw, th, mipmaps, format, img_data);
- }
+TextureLayered::LayeredType StreamTextureLayered::get_layered_type() const {
+ return layered_type;
+}
+
+RID StreamTextureLayered::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
+ }
+ return texture;
+}
+
+Ref<Image> StreamTextureLayered::get_layer_data(int p_layer) const {
+ if (texture.is_valid()) {
+ return RS::get_singleton()->texture_2d_layer_get(texture, p_layer);
+ } else {
+ return Ref<Image>();
+ }
+}
+
+void StreamTextureLayered::reload_from_file() {
+ String path = get_path();
+ if (!path.is_resource_file()) {
+ return;
+ }
- lt->set_layer_data(image, layer);
+ path = ResourceLoader::path_remap(path); //remap for translation
+ path = ResourceLoader::import_remap(path); //remap for import
+ if (!path.is_resource_file()) {
+ return;
}
- if (r_error)
- *r_error = OK;
+ load(path);
+}
- return lt;
+void StreamTextureLayered::_validate_property(PropertyInfo &property) const {
}
-void ResourceFormatLoaderTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
+void StreamTextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &StreamTextureLayered::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTextureLayered::get_load_path);
- p_extensions->push_back("tex3d");
- p_extensions->push_back("texarr");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
}
-bool ResourceFormatLoaderTextureLayered::handles_type(const String &p_type) const {
- return p_type == "Texture3D" || p_type == "TextureArray";
+
+StreamTextureLayered::StreamTextureLayered(LayeredType p_type) {
+ layered_type = p_type;
+ format = Image::FORMAT_MAX;
+ w = 0;
+ h = 0;
+ layers = 0;
+ mipmaps = false;
}
-String ResourceFormatLoaderTextureLayered::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "tex3d")
- return "Texture3D";
- if (p_path.get_extension().to_lower() == "texarr")
- return "TextureArray";
+StreamTextureLayered::~StreamTextureLayered() {
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
+}
+
+/////////////////////////////////////////////////
+
+RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ Ref<StreamTextureLayered> st;
+ if (p_path.get_extension().to_lower() == "stexarray") {
+ Ref<StreamTexture2DArray> s;
+ s.instance();
+ st = s;
+ } else if (p_path.get_extension().to_lower() == "scube") {
+ Ref<StreamCubemap> s;
+ s.instance();
+ st = s;
+ } else if (p_path.get_extension().to_lower() == "scubearray") {
+ Ref<StreamCubemapArray> s;
+ s.instance();
+ st = s;
+ } else {
+ if (r_error) {
+ *r_error = ERR_FILE_UNRECOGNIZED;
+ }
+ return RES();
+ }
+ Error err = st->load(p_path);
+ if (r_error) {
+ *r_error = err;
+ }
+ if (err != OK) {
+ return RES();
+ }
+
+ return st;
+}
+
+void ResourceFormatLoaderStreamTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("stexarray");
+ p_extensions->push_back("scube");
+ p_extensions->push_back("scubearray");
+}
+
+bool ResourceFormatLoaderStreamTextureLayered::handles_type(const String &p_type) const {
+ return p_type == "StreamTexture2DArray" || p_type == "StreamCubemap" || p_type == "StreamCubemapArray";
+}
+
+String ResourceFormatLoaderStreamTextureLayered::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "stexarray") {
+ return "StreamTexture2DArray";
+ }
+ if (p_path.get_extension().to_lower() == "scube") {
+ return "StreamCubemap";
+ }
+ if (p_path.get_extension().to_lower() == "scubearray") {
+ return "StreamCubemapArray";
+ }
return "";
}
+///////////////////////////////
+
void CameraTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_camera_feed_id", "feed_id"), &CameraTexture::set_camera_feed_id);
ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &CameraTexture::get_camera_feed_id);
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index fa698d387b..eebbf4f233 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -33,6 +33,7 @@
#include "core/io/resource_loader.h"
#include "core/math/rect2.h"
+#include "core/os/file_access.h"
#include "core/os/mutex.h"
#include "core/os/rw_lock.h"
#include "core/os/thread_safe.h"
@@ -40,137 +41,107 @@
#include "scene/resources/curve.h"
#include "scene/resources/gradient.h"
#include "servers/camera_server.h"
-#include "servers/visual_server.h"
+#include "servers/rendering_server.h"
class Texture : public Resource {
-
GDCLASS(Texture, Resource);
- OBJ_SAVE_TYPE(Texture); // Saves derived classes with common type so they can be interchanged.
+
+public:
+ Texture() {}
+};
+
+class Texture2D : public Texture {
+ GDCLASS(Texture2D, Texture);
+ OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged.
protected:
static void _bind_methods();
public:
- enum Flags {
- FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS,
- FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT,
- FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER,
- FLAG_ANISOTROPIC_FILTER = VisualServer::TEXTURE_FLAG_ANISOTROPIC_FILTER,
- FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR,
- FLAG_VIDEO_SURFACE = VisualServer::TEXTURE_FLAG_USED_FOR_STREAMING,
- FLAGS_DEFAULT = FLAG_MIPMAPS | FLAG_REPEAT | FLAG_FILTER,
- FLAG_MIRRORED_REPEAT = VisualServer::TEXTURE_FLAG_MIRRORED_REPEAT
- };
-
virtual int get_width() const = 0;
virtual int get_height() const = 0;
virtual Size2 get_size() const;
- virtual RID get_rid() const = 0;
virtual bool is_pixel_opaque(int p_x, int p_y) const;
virtual bool has_alpha() const = 0;
- virtual void set_flags(uint32_t p_flags) = 0;
- virtual uint32_t get_flags() const = 0;
-
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
virtual Ref<Image> get_data() const { return Ref<Image>(); }
- Texture();
+ Texture2D();
};
-VARIANT_ENUM_CAST(Texture::Flags);
-
class BitMap;
-class ImageTexture : public Texture {
-
- GDCLASS(ImageTexture, Texture);
+class ImageTexture : public Texture2D {
+ GDCLASS(ImageTexture, Texture2D);
RES_BASE_EXTENSION("tex");
-public:
- enum Storage {
- STORAGE_RAW,
- STORAGE_COMPRESS_LOSSY,
- STORAGE_COMPRESS_LOSSLESS
- };
-
-private:
- RID texture;
+ mutable RID texture;
Image::Format format;
- uint32_t flags;
+ bool mipmaps;
int w, h;
- Storage storage;
Size2 size_override;
- float lossy_storage_quality;
mutable Ref<BitMap> alpha_cache;
bool image_stored;
protected:
- virtual void reload_from_file();
+ virtual void reload_from_file() override;
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
void _reload_hook(const RID &p_hook);
- virtual void _resource_path_changed();
+ virtual void _resource_path_changed() override;
static void _bind_methods();
- void _set_data(Dictionary p_data);
-
public:
- void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
- void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT);
+ void create_from_image(const Ref<Image> &p_image);
- void set_flags(uint32_t p_flags);
- uint32_t get_flags() const;
Image::Format get_format() const;
-#ifndef DISABLE_DEPRECATED
- Error load(const String &p_path);
-#endif
- void set_data(const Ref<Image> &p_image);
- Ref<Image> get_data() const;
- int get_width() const;
- int get_height() const;
+ void update(const Ref<Image> &p_image, bool p_immediate = false);
+ Ref<Image> get_data() const override;
- virtual RID get_rid() const;
+ int get_width() const override;
+ int get_height() const override;
- bool has_alpha() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
- void set_storage(Storage p_storage);
- Storage get_storage() const;
+ virtual RID get_rid() const override;
- bool is_pixel_opaque(int p_x, int p_y) const;
+ bool has_alpha() const override;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const override;
- void set_lossy_storage_quality(float p_lossy_storage_quality);
- float get_lossy_storage_quality() const;
+ bool is_pixel_opaque(int p_x, int p_y) const override;
void set_size_override(const Size2 &p_size);
- virtual void set_path(const String &p_path, bool p_take_over = false);
+ virtual void set_path(const String &p_path, bool p_take_over = false) override;
ImageTexture();
~ImageTexture();
};
-class StreamTexture : public Texture {
-
- GDCLASS(StreamTexture, Texture);
+class StreamTexture2D : public Texture2D {
+ GDCLASS(StreamTexture2D, Texture2D);
public:
enum DataFormat {
DATA_FORMAT_IMAGE,
DATA_FORMAT_LOSSLESS,
- DATA_FORMAT_LOSSY
+ DATA_FORMAT_LOSSY,
+ DATA_FORMAT_BASIS_UNIVERSAL,
+ };
+
+ enum {
+ FORMAT_VERSION = 1
};
enum FormatBits {
@@ -180,78 +151,76 @@ public:
FORMAT_BIT_STREAM = 1 << 22,
FORMAT_BIT_HAS_MIPMAPS = 1 << 23,
FORMAT_BIT_DETECT_3D = 1 << 24,
- FORMAT_BIT_DETECT_SRGB = 1 << 25,
+ //FORMAT_BIT_DETECT_SRGB = 1 << 25,
FORMAT_BIT_DETECT_NORMAL = 1 << 26,
+ FORMAT_BIT_DETECT_ROUGNESS = 1 << 27,
};
private:
- Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit = 0);
+ Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0);
String path_to_file;
- RID texture;
+ mutable RID texture;
Image::Format format;
- uint32_t flags;
int w, h;
mutable Ref<BitMap> alpha_cache;
- virtual void reload_from_file();
+ virtual void reload_from_file() override;
static void _requested_3d(void *p_ud);
- static void _requested_srgb(void *p_ud);
+ static void _requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel);
static void _requested_normal(void *p_ud);
protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
- typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture> &);
+ static Ref<Image> load_image_from_file(FileAccess *p_file, int p_size_limit);
+
+ typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture2D> &);
+ typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<StreamTexture2D> &, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel);
static TextureFormatRequestCallback request_3d_callback;
- static TextureFormatRequestCallback request_srgb_callback;
+ static TextureFormatRoughnessRequestCallback request_roughness_callback;
static TextureFormatRequestCallback request_normal_callback;
- uint32_t get_flags() const;
Image::Format get_format() const;
Error load(const String &p_path);
String get_load_path() const;
- int get_width() const;
- int get_height() const;
- virtual RID get_rid() const;
+ int get_width() const override;
+ int get_height() const override;
+ virtual RID get_rid() const override;
- virtual void set_path(const String &p_path, bool p_take_over);
+ virtual void set_path(const String &p_path, bool p_take_over) override;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const override;
- virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
- bool is_pixel_opaque(int p_x, int p_y) const;
+ virtual bool has_alpha() const override;
+ bool is_pixel_opaque(int p_x, int p_y) const override;
- virtual Ref<Image> get_data() const;
+ virtual Ref<Image> get_data() const override;
- StreamTexture();
- ~StreamTexture();
+ StreamTexture2D();
+ ~StreamTexture2D();
};
-class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader {
+class ResourceFormatLoaderStreamTexture2D : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
-VARIANT_ENUM_CAST(ImageTexture::Storage);
-
-class AtlasTexture : public Texture {
-
- GDCLASS(AtlasTexture, Texture);
+class AtlasTexture : public Texture2D {
+ GDCLASS(AtlasTexture, Texture2D);
RES_BASE_EXTENSION("atlastex");
protected:
- Ref<Texture> atlas;
+ Ref<Texture2D> atlas;
Rect2 region;
Rect2 margin;
bool filter_clip;
@@ -259,17 +228,14 @@ protected:
static void _bind_methods();
public:
- virtual int get_width() const;
- virtual int get_height() const;
- virtual RID get_rid() const;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual RID get_rid() const override;
- virtual bool has_alpha() const;
+ virtual bool has_alpha() const override;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
- void set_atlas(const Ref<Texture> &p_atlas);
- Ref<Texture> get_atlas() const;
+ void set_atlas(const Ref<Texture2D> &p_atlas);
+ Ref<Texture2D> get_atlas() const;
void set_region(const Rect2 &p_region);
Rect2 get_region() const;
@@ -280,24 +246,23 @@ public:
void set_filter_clip(const bool p_enable);
bool has_filter_clip() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
- virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const override;
+ virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const override;
- bool is_pixel_opaque(int p_x, int p_y) const;
+ bool is_pixel_opaque(int p_x, int p_y) const override;
AtlasTexture();
};
class Mesh;
-class MeshTexture : public Texture {
-
- GDCLASS(MeshTexture, Texture);
+class MeshTexture : public Texture2D {
+ GDCLASS(MeshTexture, Texture2D);
RES_BASE_EXTENSION("meshtex");
- Ref<Texture> base_texture;
+ Ref<Texture2D> base_texture;
Ref<Mesh> mesh;
Size2i size;
@@ -305,14 +270,11 @@ protected:
static void _bind_methods();
public:
- virtual int get_width() const;
- virtual int get_height() const;
- virtual RID get_rid() const;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual RID get_rid() const override;
- virtual bool has_alpha() const;
-
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
+ virtual bool has_alpha() const override;
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
@@ -320,29 +282,27 @@ public:
void set_image_size(const Size2 &p_size);
Size2 get_image_size() const;
- void set_base_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_base_texture() const;
+ void set_base_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_base_texture() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
- virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const override;
+ virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const override;
- bool is_pixel_opaque(int p_x, int p_y) const;
+ bool is_pixel_opaque(int p_x, int p_y) const override;
MeshTexture();
};
-class LargeTexture : public Texture {
-
- GDCLASS(LargeTexture, Texture);
+class LargeTexture : public Texture2D {
+ GDCLASS(LargeTexture, Texture2D);
RES_BASE_EXTENSION("largetex");
protected:
struct Piece {
-
Point2 offset;
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
};
Vector<Piece> pieces;
@@ -353,208 +313,330 @@ protected:
static void _bind_methods();
public:
- virtual int get_width() const;
- virtual int get_height() const;
- virtual RID get_rid() const;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual RID get_rid() const override;
- virtual bool has_alpha() const;
+ virtual bool has_alpha() const override;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
- int add_piece(const Point2 &p_offset, const Ref<Texture> &p_texture);
+ int add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture);
void set_piece_offset(int p_idx, const Point2 &p_offset);
- void set_piece_texture(int p_idx, const Ref<Texture> &p_texture);
+ void set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture);
void set_size(const Size2 &p_size);
void clear();
int get_piece_count() const;
Vector2 get_piece_offset(int p_idx) const;
- Ref<Texture> get_piece_texture(int p_idx) const;
+ Ref<Texture2D> get_piece_texture(int p_idx) const;
Ref<Image> to_image() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const override;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), RS::CanvasItemTextureFilter p_texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const override;
- bool is_pixel_opaque(int p_x, int p_y) const;
+ bool is_pixel_opaque(int p_x, int p_y) const override;
LargeTexture();
};
-class CubeMap : public Resource {
+class TextureLayered : public Texture {
+ GDCLASS(TextureLayered, Texture);
- GDCLASS(CubeMap, Resource);
- RES_BASE_EXTENSION("cubemap");
+protected:
+ static void _bind_methods();
public:
- enum Storage {
- STORAGE_RAW,
- STORAGE_COMPRESS_LOSSY,
- STORAGE_COMPRESS_LOSSLESS
+ enum LayeredType {
+ LAYERED_TYPE_2D_ARRAY,
+ LAYERED_TYPE_CUBEMAP,
+ LAYERED_TYPE_CUBEMAP_ARRAY
};
- enum Side {
+ virtual Image::Format get_format() const = 0;
+ virtual LayeredType get_layered_type() const = 0;
+ virtual int get_width() const = 0;
+ virtual int get_height() const = 0;
+ virtual int get_layers() const = 0;
+ virtual bool has_mipmaps() const = 0;
+ virtual Ref<Image> get_layer_data(int p_layer) const = 0;
+};
- SIDE_LEFT,
- SIDE_RIGHT,
- SIDE_BOTTOM,
- SIDE_TOP,
- SIDE_FRONT,
- SIDE_BACK
- };
+VARIANT_ENUM_CAST(TextureLayered::LayeredType)
- enum Flags {
- FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS,
- FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT,
- FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER,
- FLAGS_DEFAULT = FLAG_MIPMAPS | FLAG_REPEAT | FLAG_FILTER,
- };
+class ImageTextureLayered : public TextureLayered {
+ GDCLASS(ImageTextureLayered, TextureLayered);
-private:
- bool valid[6];
- RID cubemap;
+ LayeredType layered_type;
+
+ mutable RID texture;
Image::Format format;
- uint32_t flags;
- int w, h;
- Storage storage;
- Size2 size_override;
- float lossy_storage_quality;
- _FORCE_INLINE_ bool _is_valid() const {
- for (int i = 0; i < 6; i++) {
- if (valid[i]) return true;
- }
- return false;
- }
+ int width;
+ int height;
+ int layers;
+ bool mipmaps;
-protected:
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
+ Error _create_from_images(const Array &p_images);
+
+ Array _get_images() const;
+protected:
static void _bind_methods();
public:
- void set_flags(uint32_t p_flags);
- uint32_t get_flags() const;
- void set_side(Side p_side, const Ref<Image> &p_image);
- Ref<Image> get_side(Side p_side) const;
-
- Image::Format get_format() const;
- int get_width() const;
- int get_height() const;
+ virtual Image::Format get_format() const override;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual int get_layers() const override;
+ virtual bool has_mipmaps() const override;
+ virtual LayeredType get_layered_type() const override;
+
+ Error create_from_images(Vector<Ref<Image>> p_images);
+ void update_layer(const Ref<Image> &p_image, int p_layer);
+ virtual Ref<Image> get_layer_data(int p_layer) const override;
+
+ virtual RID get_rid() const override;
+ virtual void set_path(const String &p_path, bool p_take_over = false) override;
+
+ ImageTextureLayered(LayeredType p_layered_type);
+ ~ImageTextureLayered();
+};
- virtual RID get_rid() const;
+class Texture2DArray : public ImageTextureLayered {
+ GDCLASS(Texture2DArray, ImageTextureLayered)
+public:
+ Texture2DArray() :
+ ImageTextureLayered(LAYERED_TYPE_2D_ARRAY) {}
+};
- void set_storage(Storage p_storage);
- Storage get_storage() const;
+class Cubemap : public ImageTextureLayered {
+ GDCLASS(Cubemap, ImageTextureLayered);
- void set_lossy_storage_quality(float p_lossy_storage_quality);
- float get_lossy_storage_quality() const;
+public:
+ Cubemap() :
+ ImageTextureLayered(LAYERED_TYPE_CUBEMAP) {}
+};
- virtual void set_path(const String &p_path, bool p_take_over = false);
+class CubemapArray : public ImageTextureLayered {
+ GDCLASS(CubemapArray, ImageTextureLayered);
- CubeMap();
- ~CubeMap();
+public:
+ CubemapArray() :
+ ImageTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
};
-VARIANT_ENUM_CAST(CubeMap::Flags)
-VARIANT_ENUM_CAST(CubeMap::Side)
-VARIANT_ENUM_CAST(CubeMap::Storage)
+class StreamTextureLayered : public TextureLayered {
+ GDCLASS(StreamTextureLayered, TextureLayered);
-class TextureLayered : public Resource {
+public:
+ enum DataFormat {
+ DATA_FORMAT_IMAGE,
+ DATA_FORMAT_LOSSLESS,
+ DATA_FORMAT_LOSSY,
+ DATA_FORMAT_BASIS_UNIVERSAL,
+ };
- GDCLASS(TextureLayered, Resource);
+ enum {
+ FORMAT_VERSION = 1
+ };
-public:
- enum Flags {
- FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS,
- FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT,
- FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER,
- FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR,
- FLAGS_DEFAULT = FLAG_FILTER,
+ enum FormatBits {
+ FORMAT_MASK_IMAGE_FORMAT = (1 << 20) - 1,
+ FORMAT_BIT_LOSSLESS = 1 << 20,
+ FORMAT_BIT_LOSSY = 1 << 21,
+ FORMAT_BIT_STREAM = 1 << 22,
+ FORMAT_BIT_HAS_MIPMAPS = 1 << 23,
};
private:
- bool is_3d;
- RID texture;
+ Error _load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit = 0);
+ String path_to_file;
+ mutable RID texture;
Image::Format format;
- uint32_t flags;
-
- int width;
- int height;
- int depth;
+ int w, h, layers;
+ bool mipmaps;
+ LayeredType layered_type;
- void _set_data(const Dictionary &p_data);
- Dictionary _get_data() const;
+ virtual void reload_from_file() override;
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
- void set_flags(uint32_t p_flags);
- uint32_t get_flags() const;
+ Image::Format get_format() const override;
+ Error load(const String &p_path);
+ String get_load_path() const;
+ virtual LayeredType get_layered_type() const override;
- Image::Format get_format() const;
- uint32_t get_width() const;
- uint32_t get_height() const;
- uint32_t get_depth() const;
+ int get_width() const override;
+ int get_height() const override;
+ int get_layers() const override;
+ virtual bool has_mipmaps() const override;
+ virtual RID get_rid() const override;
- void create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
- void set_layer_data(const Ref<Image> &p_image, int p_layer);
- Ref<Image> get_layer_data(int p_layer) const;
- void set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap = 0);
+ virtual void set_path(const String &p_path, bool p_take_over) override;
- virtual RID get_rid() const;
- virtual void set_path(const String &p_path, bool p_take_over = false);
+ virtual Ref<Image> get_layer_data(int p_layer) const override;
- TextureLayered(bool p_3d = false);
- ~TextureLayered();
+ StreamTextureLayered(LayeredType p_layered_type);
+ ~StreamTextureLayered();
};
-VARIANT_ENUM_CAST(TextureLayered::Flags)
+class StreamTexture2DArray : public StreamTextureLayered {
+ GDCLASS(StreamTexture2DArray, StreamTextureLayered)
+public:
+ StreamTexture2DArray() :
+ StreamTextureLayered(LAYERED_TYPE_2D_ARRAY) {}
+};
+
+class StreamCubemap : public StreamTextureLayered {
+ GDCLASS(StreamCubemap, StreamTextureLayered);
+
+public:
+ StreamCubemap() :
+ StreamTextureLayered(LAYERED_TYPE_CUBEMAP) {}
+};
-class Texture3D : public TextureLayered {
+class StreamCubemapArray : public StreamTextureLayered {
+ GDCLASS(StreamCubemapArray, StreamTextureLayered);
- GDCLASS(Texture3D, TextureLayered);
+public:
+ StreamCubemapArray() :
+ StreamTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
+};
+class ResourceFormatLoaderStreamTextureLayered : public ResourceFormatLoader {
public:
- Texture3D() :
- TextureLayered(true) {}
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
};
-class TextureArray : public TextureLayered {
+class Texture3D : public Texture {
+ GDCLASS(Texture3D, Texture);
- GDCLASS(TextureArray, TextureLayered);
+protected:
+ static void _bind_methods();
+
+ TypedArray<Image> _get_data() const;
public:
- TextureArray() :
- TextureLayered(false) {}
+ virtual Image::Format get_format() const = 0;
+ virtual int get_width() const = 0;
+ virtual int get_height() const = 0;
+ virtual int get_depth() const = 0;
+ virtual bool has_mipmaps() const = 0;
+ virtual Vector<Ref<Image>> get_data() const = 0;
};
-class ResourceFormatLoaderTextureLayered : public ResourceFormatLoader {
+class ImageTexture3D : public Texture3D {
+ GDCLASS(ImageTexture3D, Texture3D);
+
+ mutable RID texture;
+
+ Image::Format format = Image::FORMAT_MAX;
+ int width = 1;
+ int height = 1;
+ int depth = 1;
+ bool mipmaps = false;
+
+protected:
+ static void _bind_methods();
+
+ Error _create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data);
+ void _update(const TypedArray<Image> &p_data);
+
public:
- enum Compression {
- COMPRESSION_LOSSLESS,
- COMPRESSION_VRAM,
- COMPRESSION_UNCOMPRESSED
+ virtual Image::Format get_format() const override;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual int get_depth() const override;
+ virtual bool has_mipmaps() const override;
+
+ Error create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data);
+ void update(const Vector<Ref<Image>> &p_data);
+ virtual Vector<Ref<Image>> get_data() const override;
+
+ virtual RID get_rid() const override;
+ virtual void set_path(const String &p_path, bool p_take_over = false) override;
+
+ ImageTexture3D();
+ ~ImageTexture3D();
+};
+
+class StreamTexture3D : public Texture3D {
+ GDCLASS(StreamTexture3D, Texture3D);
+
+public:
+ enum DataFormat {
+ DATA_FORMAT_IMAGE,
+ DATA_FORMAT_LOSSLESS,
+ DATA_FORMAT_LOSSY,
+ DATA_FORMAT_BASIS_UNIVERSAL,
+ };
+
+ enum {
+ FORMAT_VERSION = 1
+ };
+
+ enum FormatBits {
+ FORMAT_MASK_IMAGE_FORMAT = (1 << 20) - 1,
+ FORMAT_BIT_LOSSLESS = 1 << 20,
+ FORMAT_BIT_LOSSY = 1 << 21,
+ FORMAT_BIT_STREAM = 1 << 22,
+ FORMAT_BIT_HAS_MIPMAPS = 1 << 23,
};
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+private:
+ Error _load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps);
+ String path_to_file;
+ mutable RID texture;
+ Image::Format format;
+ int w, h, d;
+ bool mipmaps;
+
+ virtual void reload_from_file() override;
+
+protected:
+ static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
+
+public:
+ Image::Format get_format() const override;
+ Error load(const String &p_path);
+ String get_load_path() const;
+
+ int get_width() const override;
+ int get_height() const override;
+ int get_depth() const override;
+ virtual bool has_mipmaps() const override;
+ virtual RID get_rid() const override;
+
+ virtual void set_path(const String &p_path, bool p_take_over) override;
+
+ virtual Vector<Ref<Image>> get_data() const override;
+
+ StreamTexture3D();
+ ~StreamTexture3D();
+};
+
+class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader {
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
-class CurveTexture : public Texture {
-
- GDCLASS(CurveTexture, Texture);
+class CurveTexture : public Texture2D {
+ GDCLASS(CurveTexture, Texture2D);
RES_BASE_EXTENSION("curvetex")
private:
- RID _texture;
+ mutable RID _texture;
Ref<Curve> _curve;
int _width;
@@ -565,20 +647,17 @@ protected:
public:
void set_width(int p_width);
- int get_width() const;
+ int get_width() const override;
void ensure_default_setup(float p_min = 0, float p_max = 1);
void set_curve(Ref<Curve> p_curve);
Ref<Curve> get_curve() const;
- virtual RID get_rid() const;
+ virtual RID get_rid() const override;
- virtual int get_height() const { return 1; }
- virtual bool has_alpha() const { return false; }
-
- virtual void set_flags(uint32_t p_flags) {}
- virtual uint32_t get_flags() const { return FLAG_FILTER; }
+ virtual int get_height() const override { return 1; }
+ virtual bool has_alpha() const override { return false; }
CurveTexture();
~CurveTexture();
@@ -597,12 +676,11 @@ public:
*/
//VARIANT_ENUM_CAST( Texture::CubeMapSide );
-class GradientTexture : public Texture {
- GDCLASS(GradientTexture, Texture);
+class GradientTexture : public Texture2D {
+ GDCLASS(GradientTexture, Texture2D);
public:
struct Point {
-
float offset;
Color color;
bool operator<(const Point &p_ponit) const {
@@ -627,64 +705,60 @@ public:
Ref<Gradient> get_gradient() const;
void set_width(int p_width);
- int get_width() const;
-
- virtual RID get_rid() const { return texture; }
- virtual int get_height() const { return 1; }
- virtual bool has_alpha() const { return true; }
+ int get_width() const override;
- virtual void set_flags(uint32_t p_flags) {}
- virtual uint32_t get_flags() const { return FLAG_FILTER; }
+ virtual RID get_rid() const override { return texture; }
+ virtual int get_height() const override { return 1; }
+ virtual bool has_alpha() const override { return true; }
- virtual Ref<Image> get_data() const;
+ virtual Ref<Image> get_data() const override;
GradientTexture();
virtual ~GradientTexture();
};
-class ProxyTexture : public Texture {
- GDCLASS(ProxyTexture, Texture);
+class ProxyTexture : public Texture2D {
+ GDCLASS(ProxyTexture, Texture2D);
private:
- RID proxy;
- Ref<Texture> base;
+ mutable RID proxy_ph;
+ mutable RID proxy;
+ Ref<Texture2D> base;
protected:
static void _bind_methods();
public:
- void set_base(const Ref<Texture> &p_texture);
- Ref<Texture> get_base() const;
+ void set_base(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_base() const;
- virtual int get_width() const;
- virtual int get_height() const;
- virtual RID get_rid() const;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual RID get_rid() const override;
- virtual bool has_alpha() const;
-
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
+ virtual bool has_alpha() const override;
ProxyTexture();
~ProxyTexture();
};
-class AnimatedTexture : public Texture {
- GDCLASS(AnimatedTexture, Texture);
+class AnimatedTexture : public Texture2D {
+ GDCLASS(AnimatedTexture, Texture2D);
//use readers writers lock for this, since its far more times read than written to
RWLock *rw_lock;
-private:
+public:
enum {
MAX_FRAMES = 256
};
+private:
+ RID proxy_ph;
RID proxy;
struct Frame {
-
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
float delay_sec;
Frame() {
@@ -695,7 +769,8 @@ private:
Frame frames[MAX_FRAMES];
int frame_count;
int current_frame;
-
+ bool pause;
+ bool oneshot;
float fps;
float time;
@@ -706,14 +781,23 @@ private:
protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_frames(int p_frames);
int get_frames() const;
- void set_frame_texture(int p_frame, const Ref<Texture> &p_texture);
- Ref<Texture> get_frame_texture(int p_frame) const;
+ void set_current_frame(int p_frame);
+ int get_current_frame() const;
+
+ void set_pause(bool p_pause);
+ bool get_pause() const;
+
+ void set_oneshot(bool p_oneshot);
+ bool get_oneshot() const;
+
+ void set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_frame_texture(int p_frame) const;
void set_frame_delay(int p_frame, float p_delay_sec);
float get_frame_delay(int p_frame) const;
@@ -721,25 +805,22 @@ public:
void set_fps(float p_fps);
float get_fps() const;
- virtual int get_width() const;
- virtual int get_height() const;
- virtual RID get_rid() const;
-
- virtual bool has_alpha() const;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual RID get_rid() const override;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
+ virtual bool has_alpha() const override;
- virtual Ref<Image> get_data() const;
+ virtual Ref<Image> get_data() const override;
- bool is_pixel_opaque(int p_x, int p_y) const;
+ bool is_pixel_opaque(int p_x, int p_y) const override;
AnimatedTexture();
~AnimatedTexture();
};
-class CameraTexture : public Texture {
- GDCLASS(CameraTexture, Texture);
+class CameraTexture : public Texture2D {
+ GDCLASS(CameraTexture, Texture2D);
private:
int camera_feed_id;
@@ -749,15 +830,15 @@ protected:
static void _bind_methods();
public:
- virtual int get_width() const;
- virtual int get_height() const;
- virtual RID get_rid() const;
- virtual bool has_alpha() const;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual RID get_rid() const override;
+ virtual bool has_alpha() const override;
virtual void set_flags(uint32_t p_flags);
virtual uint32_t get_flags() const;
- virtual Ref<Image> get_data() const;
+ virtual Ref<Image> get_data() const override;
void set_camera_feed_id(int p_new_id);
int get_camera_feed_id() const;
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 1f2fa1d60b..6a85d357ff 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -33,116 +33,108 @@
#include "core/print_string.h"
void Theme::_emit_theme_changed() {
-
emit_changed();
}
-PoolVector<String> Theme::_get_icon_list(const String &p_type) const {
-
- PoolVector<String> ilret;
+Vector<String> Theme::_get_icon_list(const String &p_type) const {
+ Vector<String> ilret;
List<StringName> il;
get_icon_list(p_type, &il);
ilret.resize(il.size());
int i = 0;
- PoolVector<String>::Write w = ilret.write();
+ String *w = ilret.ptrw();
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
w[i] = E->get();
}
return ilret;
}
-PoolVector<String> Theme::_get_stylebox_list(const String &p_type) const {
-
- PoolVector<String> ilret;
+Vector<String> Theme::_get_stylebox_list(const String &p_type) const {
+ Vector<String> ilret;
List<StringName> il;
get_stylebox_list(p_type, &il);
ilret.resize(il.size());
int i = 0;
- PoolVector<String>::Write w = ilret.write();
+ String *w = ilret.ptrw();
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
w[i] = E->get();
}
return ilret;
}
-PoolVector<String> Theme::_get_stylebox_types(void) const {
-
- PoolVector<String> ilret;
+Vector<String> Theme::_get_stylebox_types() const {
+ Vector<String> ilret;
List<StringName> il;
get_stylebox_types(&il);
ilret.resize(il.size());
int i = 0;
- PoolVector<String>::Write w = ilret.write();
+ String *w = ilret.ptrw();
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
w[i] = E->get();
}
return ilret;
}
-PoolVector<String> Theme::_get_font_list(const String &p_type) const {
-
- PoolVector<String> ilret;
+Vector<String> Theme::_get_font_list(const String &p_type) const {
+ Vector<String> ilret;
List<StringName> il;
get_font_list(p_type, &il);
ilret.resize(il.size());
int i = 0;
- PoolVector<String>::Write w = ilret.write();
+ String *w = ilret.ptrw();
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
w[i] = E->get();
}
return ilret;
}
-PoolVector<String> Theme::_get_color_list(const String &p_type) const {
-
- PoolVector<String> ilret;
+Vector<String> Theme::_get_color_list(const String &p_type) const {
+ Vector<String> ilret;
List<StringName> il;
get_color_list(p_type, &il);
ilret.resize(il.size());
int i = 0;
- PoolVector<String>::Write w = ilret.write();
+ String *w = ilret.ptrw();
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
w[i] = E->get();
}
return ilret;
}
-PoolVector<String> Theme::_get_constant_list(const String &p_type) const {
-
- PoolVector<String> ilret;
+Vector<String> Theme::_get_constant_list(const String &p_type) const {
+ Vector<String> ilret;
List<StringName> il;
get_constant_list(p_type, &il);
ilret.resize(il.size());
int i = 0;
- PoolVector<String>::Write w = ilret.write();
+ String *w = ilret.ptrw();
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
w[i] = E->get();
}
return ilret;
}
-PoolVector<String> Theme::_get_type_list(const String &p_type) const {
-
- PoolVector<String> ilret;
+Vector<String> Theme::_get_type_list(const String &p_type) const {
+ Vector<String> ilret;
List<StringName> il;
get_type_list(&il);
ilret.resize(il.size());
int i = 0;
- PoolVector<String>::Write w = ilret.write();
+ String *w = ilret.ptrw();
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
w[i] = E->get();
}
@@ -150,32 +142,26 @@ PoolVector<String> Theme::_get_type_list(const String &p_type) const {
}
bool Theme::_set(const StringName &p_name, const Variant &p_value) {
-
String sname = p_name;
if (sname.find("/") != -1) {
-
String type = sname.get_slicec('/', 1);
String node_type = sname.get_slicec('/', 0);
String name = sname.get_slicec('/', 2);
if (type == "icons") {
-
set_icon(name, node_type, p_value);
} else if (type == "styles") {
-
set_stylebox(name, node_type, p_value);
} else if (type == "fonts") {
-
set_font(name, node_type, p_value);
} else if (type == "colors") {
-
set_color(name, node_type, p_value);
} else if (type == "constants") {
-
set_constant(name, node_type, p_value);
- } else
+ } else {
return false;
+ }
return true;
}
@@ -184,41 +170,38 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) {
}
bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
-
String sname = p_name;
if (sname.find("/") != -1) {
-
String type = sname.get_slicec('/', 1);
String node_type = sname.get_slicec('/', 0);
String name = sname.get_slicec('/', 2);
if (type == "icons") {
-
- if (!has_icon(name, node_type))
- r_ret = Ref<Texture>();
- else
+ if (!has_icon(name, node_type)) {
+ r_ret = Ref<Texture2D>();
+ } else {
r_ret = get_icon(name, node_type);
+ }
} else if (type == "styles") {
-
- if (!has_stylebox(name, node_type))
+ if (!has_stylebox(name, node_type)) {
r_ret = Ref<StyleBox>();
- else
+ } else {
r_ret = get_stylebox(name, node_type);
+ }
} else if (type == "fonts") {
-
- if (!has_font(name, node_type))
+ if (!has_font(name, node_type)) {
r_ret = Ref<Font>();
- else
+ } else {
r_ret = get_font(name, node_type);
+ }
} else if (type == "colors") {
-
r_ret = get_color(name, node_type);
} else if (type == "constants") {
-
r_ret = get_constant(name, node_type);
- } else
+ } else {
return false;
+ }
return true;
}
@@ -227,65 +210,54 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
}
void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
-
List<PropertyInfo> list;
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = icon_map.next(key))) {
-
- const StringName *key2 = NULL;
+ const StringName *key2 = nullptr;
while ((key2 = icon_map[*key].next(key2))) {
-
- list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
+ list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
}
}
- key = NULL;
+ key = nullptr;
while ((key = style_map.next(key))) {
-
- const StringName *key2 = NULL;
+ const StringName *key2 = nullptr;
while ((key2 = style_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/styles/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
}
}
- key = NULL;
+ key = nullptr;
while ((key = font_map.next(key))) {
-
- const StringName *key2 = NULL;
+ const StringName *key2 = nullptr;
while ((key2 = font_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/fonts/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
}
}
- key = NULL;
+ key = nullptr;
while ((key = color_map.next(key))) {
-
- const StringName *key2 = NULL;
+ const StringName *key2 = nullptr;
while ((key2 = color_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::COLOR, String() + *key + "/colors/" + *key2));
}
}
- key = NULL;
+ key = nullptr;
while ((key = constant_map.next(key))) {
-
- const StringName *key2 = NULL;
+ const StringName *key2 = nullptr;
while ((key2 = constant_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::INT, String() + *key + "/constants/" + *key2));
}
}
@@ -297,18 +269,18 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
-
- if (default_theme_font == p_default_font)
+ if (default_theme_font == p_default_font) {
return;
+ }
if (default_theme_font.is_valid()) {
- default_theme_font->disconnect("changed", this, "_emit_theme_changed");
+ default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
default_theme_font = p_default_font;
if (default_theme_font.is_valid()) {
- default_theme_font->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
_change_notify();
@@ -316,63 +288,56 @@ void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
}
Ref<Font> Theme::get_default_theme_font() const {
-
return default_theme_font;
}
Ref<Theme> Theme::project_default_theme;
Ref<Theme> Theme::default_theme;
-Ref<Texture> Theme::default_icon;
+Ref<Texture2D> Theme::default_icon;
Ref<StyleBox> Theme::default_style;
Ref<Font> Theme::default_font;
Ref<Theme> Theme::get_default() {
-
return default_theme;
}
void Theme::set_default(const Ref<Theme> &p_default) {
-
default_theme = p_default;
}
Ref<Theme> Theme::get_project_default() {
-
return project_default_theme;
}
void Theme::set_project_default(const Ref<Theme> &p_project_default) {
-
project_default_theme = p_project_default;
}
-void Theme::set_default_icon(const Ref<Texture> &p_icon) {
-
+void Theme::set_default_icon(const Ref<Texture2D> &p_icon) {
default_icon = p_icon;
}
-void Theme::set_default_style(const Ref<StyleBox> &p_style) {
+void Theme::set_default_style(const Ref<StyleBox> &p_style) {
default_style = p_style;
}
-void Theme::set_default_font(const Ref<Font> &p_font) {
+void Theme::set_default_font(const Ref<Font> &p_font) {
default_font = p_font;
}
-void Theme::set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture> &p_icon) {
-
+void Theme::set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture2D> &p_icon) {
//ERR_FAIL_COND(p_icon.is_null());
bool new_value = !icon_map.has(p_type) || !icon_map[p_type].has(p_name);
if (icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) {
- icon_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed");
+ icon_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
icon_map[p_type][p_name] = p_icon;
if (p_icon.is_valid()) {
- icon_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ icon_map[p_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
if (new_value) {
@@ -380,10 +345,9 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_type, const R
emit_changed();
}
}
-Ref<Texture> Theme::get_icon(const StringName &p_name, const StringName &p_type) const {
+Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_type) const {
if (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) {
-
return icon_map[p_type][p_name];
} else {
return default_icon;
@@ -391,17 +355,15 @@ Ref<Texture> Theme::get_icon(const StringName &p_name, const StringName &p_type)
}
bool Theme::has_icon(const StringName &p_name, const StringName &p_type) const {
-
return (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid());
}
void Theme::clear_icon(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!icon_map.has(p_type));
ERR_FAIL_COND(!icon_map[p_type].has(p_name));
if (icon_map[p_type][p_name].is_valid()) {
- icon_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed");
+ icon_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
icon_map[p_type].erase(p_name);
@@ -411,16 +373,15 @@ void Theme::clear_icon(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_icon_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!icon_map.has(p_type))
+ if (!icon_map.has(p_type)) {
return;
+ }
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = icon_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
@@ -440,7 +401,7 @@ Ref<Shader> Theme::get_shader(const StringName &p_name, const StringName &p_type
if (shader_map.has(p_type) && shader_map[p_type].has(p_name) && shader_map[p_type][p_name].is_valid()) {
return shader_map[p_type][p_name];
} else {
- return NULL;
+ return nullptr;
}
}
@@ -458,45 +419,42 @@ void Theme::clear_shader(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_shader_list(const StringName &p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!shader_map.has(p_type))
+ if (!shader_map.has(p_type)) {
return;
+ }
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = shader_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::set_stylebox(const StringName &p_name, const StringName &p_type, const Ref<StyleBox> &p_style) {
-
//ERR_FAIL_COND(p_style.is_null());
bool new_value = !style_map.has(p_type) || !style_map[p_type].has(p_name);
if (style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid()) {
- style_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed");
+ style_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
style_map[p_type][p_name] = p_style;
if (p_style.is_valid()) {
- style_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ style_map[p_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
- if (new_value)
+ if (new_value) {
_change_notify();
+ }
emit_changed();
}
Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_type) const {
-
if (style_map.has(p_type) && style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid()) {
-
return style_map[p_type][p_name];
} else {
return default_style;
@@ -504,17 +462,15 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_
}
bool Theme::has_stylebox(const StringName &p_name, const StringName &p_type) const {
-
return (style_map.has(p_type) && style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid());
}
void Theme::clear_stylebox(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!style_map.has(p_type));
ERR_FAIL_COND(!style_map[p_type].has(p_name));
if (style_map[p_type][p_name].is_valid()) {
- style_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed");
+ style_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
style_map[p_type].erase(p_name);
@@ -524,16 +480,15 @@ void Theme::clear_stylebox(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_stylebox_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!style_map.has(p_type))
+ if (!style_map.has(p_type)) {
return;
+ }
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = style_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
@@ -541,26 +496,25 @@ void Theme::get_stylebox_list(StringName p_type, List<StringName> *p_list) const
void Theme::get_stylebox_types(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list);
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = style_map.next(key))) {
p_list->push_back(*key);
}
}
void Theme::set_font(const StringName &p_name, const StringName &p_type, const Ref<Font> &p_font) {
-
//ERR_FAIL_COND(p_font.is_null());
bool new_value = !font_map.has(p_type) || !font_map[p_type].has(p_name);
if (font_map[p_type][p_name].is_valid()) {
- font_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed");
+ font_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
font_map[p_type][p_name] = p_font;
if (p_font.is_valid()) {
- font_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ font_map[p_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
if (new_value) {
@@ -568,28 +522,27 @@ void Theme::set_font(const StringName &p_name, const StringName &p_type, const R
emit_changed();
}
}
-Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_type) const {
- if (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid())
+Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_type) const {
+ if (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid()) {
return font_map[p_type][p_name];
- else if (default_theme_font.is_valid())
+ } else if (default_theme_font.is_valid()) {
return default_theme_font;
- else
+ } else {
return default_font;
+ }
}
bool Theme::has_font(const StringName &p_name, const StringName &p_type) const {
-
return (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid());
}
void Theme::clear_font(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!font_map.has(p_type));
ERR_FAIL_COND(!font_map[p_type].has(p_name));
if (font_map[p_type][p_name].is_valid()) {
- font_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed");
+ font_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
font_map[p_type].erase(p_name);
@@ -598,22 +551,20 @@ void Theme::clear_font(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_font_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!font_map.has(p_type))
+ if (!font_map.has(p_type)) {
return;
+ }
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = font_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::set_color(const StringName &p_name, const StringName &p_type, const Color &p_color) {
-
bool new_value = !color_map.has(p_type) || !color_map[p_type].has(p_name);
color_map[p_type][p_name] = p_color;
@@ -625,20 +576,18 @@ void Theme::set_color(const StringName &p_name, const StringName &p_type, const
}
Color Theme::get_color(const StringName &p_name, const StringName &p_type) const {
-
- if (color_map.has(p_type) && color_map[p_type].has(p_name))
+ if (color_map.has(p_type) && color_map[p_type].has(p_name)) {
return color_map[p_type][p_name];
- else
+ } else {
return Color();
+ }
}
bool Theme::has_color(const StringName &p_name, const StringName &p_type) const {
-
return (color_map.has(p_type) && color_map[p_type].has(p_name));
}
void Theme::clear_color(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!color_map.has(p_type));
ERR_FAIL_COND(!color_map[p_type].has(p_name));
@@ -648,22 +597,20 @@ void Theme::clear_color(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_color_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!color_map.has(p_type))
+ if (!color_map.has(p_type)) {
return;
+ }
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = color_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::set_constant(const StringName &p_name, const StringName &p_type, int p_constant) {
-
bool new_value = !constant_map.has(p_type) || !constant_map[p_type].has(p_name);
constant_map[p_type][p_name] = p_constant;
@@ -674,21 +621,18 @@ void Theme::set_constant(const StringName &p_name, const StringName &p_type, int
}
int Theme::get_constant(const StringName &p_name, const StringName &p_type) const {
-
- if (constant_map.has(p_type) && constant_map[p_type].has(p_name))
+ if (constant_map.has(p_type) && constant_map[p_type].has(p_name)) {
return constant_map[p_type][p_name];
- else {
+ } else {
return 0;
}
}
bool Theme::has_constant(const StringName &p_name, const StringName &p_type) const {
-
return (constant_map.has(p_type) && constant_map[p_type].has(p_name));
}
void Theme::clear_constant(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!constant_map.has(p_type));
ERR_FAIL_COND(!constant_map[p_type].has(p_name));
@@ -698,57 +642,55 @@ void Theme::clear_constant(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_constant_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!constant_map.has(p_type))
+ if (!constant_map.has(p_type)) {
return;
+ }
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = constant_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::clear() {
-
//these need disconnecting
{
- const StringName *K = NULL;
+ const StringName *K = nullptr;
while ((K = icon_map.next(K))) {
- const StringName *L = NULL;
+ const StringName *L = nullptr;
while ((L = icon_map[*K].next(L))) {
- Ref<Texture> icon = icon_map[*K][*L];
+ Ref<Texture2D> icon = icon_map[*K][*L];
if (icon.is_valid()) {
- icon->disconnect("changed", this, "_emit_theme_changed");
+ icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
}
}
}
{
- const StringName *K = NULL;
+ const StringName *K = nullptr;
while ((K = style_map.next(K))) {
- const StringName *L = NULL;
+ const StringName *L = nullptr;
while ((L = style_map[*K].next(L))) {
Ref<StyleBox> style = style_map[*K][*L];
if (style.is_valid()) {
- style->disconnect("changed", this, "_emit_theme_changed");
+ style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
}
}
}
{
- const StringName *K = NULL;
+ const StringName *K = nullptr;
while ((K = font_map.next(K))) {
- const StringName *L = NULL;
+ const StringName *L = nullptr;
while ((L = font_map[*K].next(L))) {
Ref<Font> font = font_map[*K][*L];
if (font.is_valid()) {
- font->disconnect("changed", this, "_emit_theme_changed");
+ font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
}
}
@@ -766,13 +708,11 @@ void Theme::clear() {
}
void Theme::copy_default_theme() {
-
Ref<Theme> default_theme2 = get_default();
copy_theme(default_theme2);
}
void Theme::copy_theme(const Ref<Theme> &p_other) {
-
if (p_other.is_null()) {
clear();
@@ -781,9 +721,9 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
//these need reconnecting, so add normally
{
- const StringName *K = NULL;
+ const StringName *K = nullptr;
while ((K = p_other->icon_map.next(K))) {
- const StringName *L = NULL;
+ const StringName *L = nullptr;
while ((L = p_other->icon_map[*K].next(L))) {
set_icon(*L, *K, p_other->icon_map[*K][*L]);
}
@@ -791,9 +731,9 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
}
{
- const StringName *K = NULL;
+ const StringName *K = nullptr;
while ((K = p_other->style_map.next(K))) {
- const StringName *L = NULL;
+ const StringName *L = nullptr;
while ((L = p_other->style_map[*K].next(L))) {
set_stylebox(*L, *K, p_other->style_map[*K][*L]);
}
@@ -801,9 +741,9 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
}
{
- const StringName *K = NULL;
+ const StringName *K = nullptr;
while ((K = p_other->font_map.next(K))) {
- const StringName *L = NULL;
+ const StringName *L = nullptr;
while ((L = p_other->font_map[*K].next(L))) {
set_font(*L, *K, p_other->font_map[*K][*L]);
}
@@ -821,53 +761,45 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
}
void Theme::get_type_list(List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
Set<StringName> types;
- const StringName *key = NULL;
+ const StringName *key = nullptr;
while ((key = icon_map.next(key))) {
-
types.insert(*key);
}
- key = NULL;
+ key = nullptr;
while ((key = style_map.next(key))) {
-
types.insert(*key);
}
- key = NULL;
+ key = nullptr;
while ((key = font_map.next(key))) {
-
types.insert(*key);
}
- key = NULL;
+ key = nullptr;
while ((key = color_map.next(key))) {
-
types.insert(*key);
}
- key = NULL;
+ key = nullptr;
while ((key = constant_map.next(key))) {
-
types.insert(*key);
}
for (Set<StringName>::Element *E = types.front(); E; E = E->next()) {
-
p_list->push_back(E->get());
}
}
void Theme::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_icon", "name", "type", "texture"), &Theme::set_icon);
ClassDB::bind_method(D_METHOD("get_icon", "name", "type"), &Theme::get_icon);
ClassDB::bind_method(D_METHOD("has_icon", "name", "type"), &Theme::has_icon);
@@ -906,8 +838,6 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_type_list", "type"), &Theme::_get_type_list);
- ClassDB::bind_method(D_METHOD("_emit_theme_changed"), &Theme::_emit_theme_changed);
-
ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme);
ClassDB::bind_method(D_METHOD("copy_theme", "other"), &Theme::copy_theme);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 4bb614b24e..3c72ddd8a2 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -39,26 +39,25 @@
#include "scene/resources/texture.h"
class Theme : public Resource {
-
GDCLASS(Theme, Resource);
RES_BASE_EXTENSION("theme");
void _emit_theme_changed();
- HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map;
- HashMap<StringName, HashMap<StringName, Ref<StyleBox> > > style_map;
- HashMap<StringName, HashMap<StringName, Ref<Font> > > font_map;
- HashMap<StringName, HashMap<StringName, Ref<Shader> > > shader_map;
- HashMap<StringName, HashMap<StringName, Color> > color_map;
- HashMap<StringName, HashMap<StringName, int> > constant_map;
-
- PoolVector<String> _get_icon_list(const String &p_type) const;
- PoolVector<String> _get_stylebox_list(const String &p_type) const;
- PoolVector<String> _get_stylebox_types(void) const;
- PoolVector<String> _get_font_list(const String &p_type) const;
- PoolVector<String> _get_color_list(const String &p_type) const;
- PoolVector<String> _get_constant_list(const String &p_type) const;
- PoolVector<String> _get_type_list(const String &p_type) const;
+ HashMap<StringName, HashMap<StringName, Ref<Texture2D>>> icon_map;
+ HashMap<StringName, HashMap<StringName, Ref<StyleBox>>> style_map;
+ HashMap<StringName, HashMap<StringName, Ref<Font>>> font_map;
+ HashMap<StringName, HashMap<StringName, Ref<Shader>>> shader_map;
+ HashMap<StringName, HashMap<StringName, Color>> color_map;
+ HashMap<StringName, HashMap<StringName, int>> constant_map;
+
+ Vector<String> _get_icon_list(const String &p_type) const;
+ Vector<String> _get_stylebox_list(const String &p_type) const;
+ Vector<String> _get_stylebox_types() const;
+ Vector<String> _get_font_list(const String &p_type) const;
+ Vector<String> _get_color_list(const String &p_type) const;
+ Vector<String> _get_constant_list(const String &p_type) const;
+ Vector<String> _get_type_list(const String &p_type) const;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -67,7 +66,7 @@ protected:
static Ref<Theme> project_default_theme;
static Ref<Theme> default_theme;
- static Ref<Texture> default_icon;
+ static Ref<Texture2D> default_icon;
static Ref<StyleBox> default_style;
static Ref<Font> default_font;
@@ -82,15 +81,15 @@ public:
static Ref<Theme> get_project_default();
static void set_project_default(const Ref<Theme> &p_project_default);
- static void set_default_icon(const Ref<Texture> &p_icon);
+ static void set_default_icon(const Ref<Texture2D> &p_icon);
static void set_default_style(const Ref<StyleBox> &p_style);
static void set_default_font(const Ref<Font> &p_font);
void set_default_theme_font(const Ref<Font> &p_default_font);
Ref<Font> get_default_theme_font() const;
- void set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture> &p_icon);
- Ref<Texture> get_icon(const StringName &p_name, const StringName &p_type) const;
+ void set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_type) const;
bool has_icon(const StringName &p_name, const StringName &p_type) const;
void clear_icon(const StringName &p_name, const StringName &p_type);
void get_icon_list(StringName p_type, List<StringName> *p_list) const;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 555e90ed3c..84b067d1e2 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -29,54 +29,58 @@
/*************************************************************************/
#include "tile_set.h"
+
#include "core/array.h"
#include "core/engine.h"
+#include "core/math/geometry_2d.h"
bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
-
String n = p_name;
int slash = n.find("/");
- if (slash == -1)
+ if (slash == -1) {
return false;
- int id = String::to_int(n.c_str(), slash);
+ }
+ int id = String::to_int(n.get_data(), slash);
- if (!tile_map.has(id))
+ if (!tile_map.has(id)) {
create_tile(id);
+ }
String what = n.substr(slash + 1, n.length());
- if (what == "name")
+ if (what == "name") {
tile_set_name(id, p_value);
- else if (what == "texture")
+ } else if (what == "texture") {
tile_set_texture(id, p_value);
- else if (what == "normal_map")
+ } else if (what == "normal_map") {
tile_set_normal_map(id, p_value);
- else if (what == "tex_offset")
+ } else if (what == "tex_offset") {
tile_set_texture_offset(id, p_value);
- else if (what == "material")
+ } else if (what == "material") {
tile_set_material(id, p_value);
- else if (what == "modulate")
+ } else if (what == "modulate") {
tile_set_modulate(id, p_value);
- else if (what == "region")
+ } else if (what == "region") {
tile_set_region(id, p_value);
- else if (what == "tile_mode")
+ } else if (what == "tile_mode") {
tile_set_tile_mode(id, (TileMode)((int)p_value));
- else if (what == "is_autotile") {
+ } else if (what == "is_autotile") {
// backward compatibility for Godot 3.0.x
// autotile used to be a bool, it's now an enum
bool is_autotile = p_value;
- if (is_autotile)
+ if (is_autotile) {
tile_set_tile_mode(id, AUTO_TILE);
+ }
} else if (what.left(9) == "autotile/") {
what = what.right(9);
- if (what == "bitmask_mode")
+ if (what == "bitmask_mode") {
autotile_set_bitmask_mode(id, (BitmaskMode)((int)p_value));
- else if (what == "icon_coordinate")
+ } else if (what == "icon_coordinate") {
autotile_set_icon_coordinate(id, p_value);
- else if (what == "tile_size")
+ } else if (what == "tile_size") {
autotile_set_size(id, p_value);
- else if (what == "spacing")
+ } else if (what == "spacing") {
autotile_set_spacing(id, p_value);
- else if (what == "bitmask_flags") {
+ } else if (what == "bitmask_flags") {
tile_map[id].autotile_data.flags.clear();
if (p_value.is_array()) {
Array p = p_value;
@@ -147,7 +151,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
p.pop_front();
}
}
- } else if (what == "shape")
+ } else if (what == "shape") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape(id, i, p_value);
@@ -155,7 +159,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape(id, 0, p_value);
}
- else if (what == "shape_offset")
+ } else if (what == "shape_offset") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_offset(id, i, p_value);
@@ -163,7 +167,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_offset(id, 0, p_value);
}
- else if (what == "shape_transform")
+ } else if (what == "shape_transform") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_transform(id, i, p_value);
@@ -171,7 +175,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_transform(id, 0, p_value);
}
- else if (what == "shape_one_way")
+ } else if (what == "shape_one_way") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_one_way(id, i, p_value);
@@ -179,7 +183,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_one_way(id, 0, p_value);
}
- else if (what == "shape_one_way_margin")
+ } else if (what == "shape_one_way_margin") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_one_way_margin(id, i, p_value);
@@ -187,63 +191,64 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_one_way_margin(id, 0, p_value);
}
- else if (what == "shapes")
+ } else if (what == "shapes") {
_tile_set_shapes(id, p_value);
- else if (what == "occluder")
+ } else if (what == "occluder") {
tile_set_light_occluder(id, p_value);
- else if (what == "occluder_offset")
+ } else if (what == "occluder_offset") {
tile_set_occluder_offset(id, p_value);
- else if (what == "navigation")
+ } else if (what == "navigation") {
tile_set_navigation_polygon(id, p_value);
- else if (what == "navigation_offset")
+ } else if (what == "navigation_offset") {
tile_set_navigation_polygon_offset(id, p_value);
- else if (what == "z_index")
+ } else if (what == "z_index") {
tile_set_z_index(id, p_value);
- else
+ } else {
return false;
+ }
return true;
}
bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
-
String n = p_name;
int slash = n.find("/");
- if (slash == -1)
+ if (slash == -1) {
return false;
- int id = String::to_int(n.c_str(), slash);
+ }
+ int id = String::to_int(n.get_data(), slash);
ERR_FAIL_COND_V(!tile_map.has(id), false);
String what = n.substr(slash + 1, n.length());
- if (what == "name")
+ if (what == "name") {
r_ret = tile_get_name(id);
- else if (what == "texture")
+ } else if (what == "texture") {
r_ret = tile_get_texture(id);
- else if (what == "normal_map")
+ } else if (what == "normal_map") {
r_ret = tile_get_normal_map(id);
- else if (what == "tex_offset")
+ } else if (what == "tex_offset") {
r_ret = tile_get_texture_offset(id);
- else if (what == "material")
+ } else if (what == "material") {
r_ret = tile_get_material(id);
- else if (what == "modulate")
+ } else if (what == "modulate") {
r_ret = tile_get_modulate(id);
- else if (what == "region")
+ } else if (what == "region") {
r_ret = tile_get_region(id);
- else if (what == "tile_mode")
+ } else if (what == "tile_mode") {
r_ret = tile_get_tile_mode(id);
- else if (what.left(9) == "autotile/") {
+ } else if (what.left(9) == "autotile/") {
what = what.right(9);
- if (what == "bitmask_mode")
+ if (what == "bitmask_mode") {
r_ret = autotile_get_bitmask_mode(id);
- else if (what == "icon_coordinate")
+ } else if (what == "icon_coordinate") {
r_ret = autotile_get_icon_coordinate(id);
- else if (what == "tile_size")
+ } else if (what == "tile_size") {
r_ret = autotile_get_size(id);
- else if (what == "spacing")
+ } else if (what == "spacing") {
r_ret = autotile_get_spacing(id);
- else if (what == "bitmask_flags") {
+ } else if (what == "bitmask_flags") {
Array p;
for (Map<Vector2, uint32_t>::Element *E = tile_map[id].autotile_data.flags.front(); E; E = E->next()) {
p.push_back(E->key());
@@ -252,14 +257,14 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = p;
} else if (what == "occluder_map") {
Array p;
- for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = tile_map[id].autotile_data.occluder_map.front(); E; E = E->next()) {
+ for (Map<Vector2, Ref<OccluderPolygon2D>>::Element *E = tile_map[id].autotile_data.occluder_map.front(); E; E = E->next()) {
p.push_back(E->key());
p.push_back(E->value());
}
r_ret = p;
} else if (what == "navpoly_map") {
Array p;
- for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = tile_map[id].autotile_data.navpoly_map.front(); E; E = E->next()) {
+ for (Map<Vector2, Ref<NavigationPolygon>>::Element *E = tile_map[id].autotile_data.navpoly_map.front(); E; E = E->next()) {
p.push_back(E->key());
p.push_back(E->value());
}
@@ -291,48 +296,47 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
}
r_ret = p;
}
- } else if (what == "shape")
+ } else if (what == "shape") {
r_ret = tile_get_shape(id, 0);
- else if (what == "shape_offset")
+ } else if (what == "shape_offset") {
r_ret = tile_get_shape_offset(id, 0);
- else if (what == "shape_transform")
+ } else if (what == "shape_transform") {
r_ret = tile_get_shape_transform(id, 0);
- else if (what == "shape_one_way")
+ } else if (what == "shape_one_way") {
r_ret = tile_get_shape_one_way(id, 0);
- else if (what == "shape_one_way_margin")
+ } else if (what == "shape_one_way_margin") {
r_ret = tile_get_shape_one_way_margin(id, 0);
- else if (what == "shapes")
+ } else if (what == "shapes") {
r_ret = _tile_get_shapes(id);
- else if (what == "occluder")
+ } else if (what == "occluder") {
r_ret = tile_get_light_occluder(id);
- else if (what == "occluder_offset")
+ } else if (what == "occluder_offset") {
r_ret = tile_get_occluder_offset(id);
- else if (what == "navigation")
+ } else if (what == "navigation") {
r_ret = tile_get_navigation_polygon(id);
- else if (what == "navigation_offset")
+ } else if (what == "navigation_offset") {
r_ret = tile_get_navigation_polygon_offset(id);
- else if (what == "z_index")
+ } else if (what == "z_index") {
r_ret = tile_get_z_index(id);
- else
+ } else {
return false;
+ }
return true;
}
void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
-
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
-
int id = E->key();
String pre = itos(id) + "/";
- p_list->push_back(PropertyInfo(Variant::STRING, pre + "name"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "tex_offset"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial"));
- p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate"));
- p_list->push_back(PropertyInfo(Variant::RECT2, pre + "region"));
- p_list->push_back(PropertyInfo(Variant::INT, pre + "tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE,ATLAS_TILE"));
+ p_list->push_back(PropertyInfo(Variant::STRING, pre + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "tex_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::RECT2, pre + "region", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE,ATLAS_TILE", PROPERTY_USAGE_NOEDITOR));
if (tile_get_tile_mode(id) == AUTO_TILE) {
p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/bitmask_mode", PROPERTY_HINT_ENUM, "2X2,3X3 (minimal),3X3", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/bitmask_flags", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -352,17 +356,17 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/z_index_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "navigation_offset"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "navigation", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::BOOL, pre + "shape_one_way", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::REAL, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "navigation_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "navigation", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::BOOL, pre + "shape_one_way", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1", PROPERTY_USAGE_NOEDITOR));
}
}
@@ -382,53 +386,45 @@ void TileSet::autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode) {
}
TileSet::BitmaskMode TileSet::autotile_get_bitmask_mode(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), BITMASK_2X2);
return tile_map[p_id].autotile_data.bitmask_mode;
}
-void TileSet::tile_set_texture(int p_id, const Ref<Texture> &p_texture) {
-
+void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].texture = p_texture;
emit_changed();
_change_notify("texture");
}
-Ref<Texture> TileSet::tile_get_texture(int p_id) const {
-
- ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture>());
+Ref<Texture2D> TileSet::tile_get_texture(int p_id) const {
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>());
return tile_map[p_id].texture;
}
-void TileSet::tile_set_normal_map(int p_id, const Ref<Texture> &p_normal_map) {
-
+void TileSet::tile_set_normal_map(int p_id, const Ref<Texture2D> &p_normal_map) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].normal_map = p_normal_map;
emit_changed();
}
-Ref<Texture> TileSet::tile_get_normal_map(int p_id) const {
-
- ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture>());
+Ref<Texture2D> TileSet::tile_get_normal_map(int p_id) const {
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>());
return tile_map[p_id].normal_map;
}
void TileSet::tile_set_material(int p_id, const Ref<ShaderMaterial> &p_material) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].material = p_material;
emit_changed();
}
Ref<ShaderMaterial> TileSet::tile_get_material(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<ShaderMaterial>());
return tile_map[p_id].material;
}
void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].modulate = p_modulate;
emit_changed();
@@ -436,26 +432,22 @@ void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) {
}
Color TileSet::tile_get_modulate(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Color(1, 1, 1));
return tile_map[p_id].modulate;
}
void TileSet::tile_set_texture_offset(int p_id, const Vector2 &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].offset = p_offset;
emit_changed();
}
Vector2 TileSet::tile_get_texture_offset(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].offset;
}
void TileSet::tile_set_region(int p_id, const Rect2 &p_region) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].region = p_region;
emit_changed();
@@ -463,7 +455,6 @@ void TileSet::tile_set_region(int p_id, const Rect2 &p_region) {
}
Rect2 TileSet::tile_get_region(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Rect2());
return tile_map[p_id].region;
}
@@ -476,26 +467,22 @@ void TileSet::tile_set_tile_mode(int p_id, TileMode p_tile_mode) {
}
TileSet::TileMode TileSet::tile_get_tile_mode(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), SINGLE_TILE);
return tile_map[p_id].tile_mode;
}
void TileSet::autotile_set_icon_coordinate(int p_id, Vector2 coord) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].autotile_data.icon_coord = coord;
emit_changed();
}
Vector2 TileSet::autotile_get_icon_coordinate(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].autotile_data.icon_coord;
}
void TileSet::autotile_set_spacing(int p_id, int p_spacing) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_spacing < 0);
tile_map[p_id].autotile_data.spacing = p_spacing;
@@ -503,39 +490,33 @@ void TileSet::autotile_set_spacing(int p_id, int p_spacing) {
}
int TileSet::autotile_get_spacing(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
return tile_map[p_id].autotile_data.spacing;
}
void TileSet::autotile_set_size(int p_id, Size2 p_size) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_size.x <= 0 || p_size.y <= 0);
tile_map[p_id].autotile_data.size = p_size;
}
Size2 TileSet::autotile_get_size(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Size2());
return tile_map[p_id].autotile_data.size;
}
void TileSet::autotile_clear_bitmask_map(int p_id) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].autotile_data.flags.clear();
}
void TileSet::autotile_set_subtile_priority(int p_id, const Vector2 &p_coord, int p_priority) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_priority <= 0);
tile_map[p_id].autotile_data.priority_map[p_coord] = p_priority;
}
int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 1);
if (tile_map[p_id].autotile_data.priority_map.has(p_coord)) {
return tile_map[p_id].autotile_data.priority_map[p_coord];
@@ -545,21 +526,18 @@ int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
}
const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
-
static Map<Vector2, int> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.priority_map;
}
void TileSet::autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].autotile_data.z_index_map[p_coord] = p_z_index;
emit_changed();
}
int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 1);
if (tile_map[p_id].autotile_data.z_index_map.has(p_coord)) {
return tile_map[p_id].autotile_data.z_index_map[p_coord];
@@ -569,25 +547,23 @@ int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) {
}
const Map<Vector2, int> &TileSet::autotile_get_z_index_map(int p_id) const {
-
static Map<Vector2, int> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.z_index_map;
}
void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
if (p_flag == 0) {
- if (tile_map[p_id].autotile_data.flags.has(p_coord))
+ if (tile_map[p_id].autotile_data.flags.has(p_coord)) {
tile_map[p_id].autotile_data.flags.erase(p_coord);
+ }
} else {
tile_map[p_id].autotile_data.flags[p_coord] = p_flag;
}
}
uint32_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
if (!tile_map[p_id].autotile_data.flags.has(p_coord)) {
return 0;
@@ -596,7 +572,6 @@ uint32_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
}
const Map<Vector2, uint32_t> &TileSet::autotile_get_bitmask_map(int p_id) {
-
static Map<Vector2, uint32_t> dummy;
static Map<Vector2, uint32_t> dummy_atlas;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
@@ -611,16 +586,16 @@ const Map<Vector2, uint32_t> &TileSet::autotile_get_bitmask_map(int p_id) {
}
}
return dummy_atlas;
- } else
+ } else {
return tile_map[p_id].autotile_data.flags;
+ }
}
Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node, const Vector2 &p_tile_location) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
//First try to forward selection to script
if (p_tilemap_node->get_class_name() == "TileMap") {
- if (get_script_instance() != NULL) {
+ if (get_script_instance() != nullptr) {
if (get_script_instance()->has_method("_forward_subtile_selection")) {
Variant ret = get_script_instance()->call("_forward_subtile_selection", p_id, p_bitmask, p_tilemap_node, p_tile_location);
if (ret.get_type() == Variant::VECTOR2) {
@@ -678,10 +653,9 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask,
}
Vector2 TileSet::atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node, const Vector2 &p_tile_location) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
//First try to forward selection to script
- if (get_script_instance() != NULL) {
+ if (get_script_instance() != nullptr) {
if (get_script_instance()->has_method("_forward_atlas_subtile_selection")) {
Variant ret = get_script_instance()->call("_forward_atlas_subtile_selection", p_id, p_tilemap_node, p_tile_location);
if (ret.get_type() == Variant::VECTOR2) {
@@ -708,7 +682,6 @@ Vector2 TileSet::atlastile_get_subtile_by_priority(int p_id, const Node *p_tilem
}
void TileSet::tile_set_name(int p_id, const String &p_name) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].name = p_name;
emit_changed();
@@ -716,19 +689,16 @@ void TileSet::tile_set_name(int p_id, const String &p_name) {
}
String TileSet::tile_get_name(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), String());
return tile_map[p_id].name;
}
void TileSet::tile_clear_shapes(int p_id) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].shapes_data.clear();
}
void TileSet::tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way, const Vector2 &p_autotile_coord) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ShapeData new_data = ShapeData();
@@ -741,52 +711,51 @@ void TileSet::tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transf
}
int TileSet::tile_get_shape_count(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
return tile_map[p_id].shapes_data.size();
}
void TileSet::tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].shape = p_shape;
_decompose_convex_shape(p_shape);
emit_changed();
}
Ref<Shape2D> TileSet::tile_get_shape(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Shape2D>());
ERR_FAIL_COND_V(p_shape_id < 0, Ref<Shape2D>());
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].shape;
+ }
return Ref<Shape2D>();
}
void TileSet::tile_set_shape_transform(int p_id, int p_shape_id, const Transform2D &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].shape_transform = p_offset;
emit_changed();
}
Transform2D TileSet::tile_get_shape_transform(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Transform2D());
ERR_FAIL_COND_V(p_shape_id < 0, Transform2D());
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].shape_transform;
+ }
return Transform2D();
}
@@ -802,57 +771,55 @@ Vector2 TileSet::tile_get_shape_offset(int p_id, int p_shape_id) const {
}
void TileSet::tile_set_shape_one_way(int p_id, int p_shape_id, const bool p_one_way) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].one_way_collision = p_one_way;
emit_changed();
}
bool TileSet::tile_get_shape_one_way(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), false);
ERR_FAIL_COND_V(p_shape_id < 0, false);
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].one_way_collision;
+ }
return false;
}
void TileSet::tile_set_shape_one_way_margin(int p_id, int p_shape_id, float p_margin) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].one_way_collision_margin = p_margin;
emit_changed();
}
float TileSet::tile_get_shape_one_way_margin(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
ERR_FAIL_COND_V(p_shape_id < 0, 0);
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].one_way_collision_margin;
+ }
return 0;
}
void TileSet::tile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].occluder = p_light_occluder;
}
Ref<OccluderPolygon2D> TileSet::tile_get_light_occluder(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<OccluderPolygon2D>());
return tile_map[p_id].occluder;
}
@@ -869,7 +836,6 @@ void TileSet::autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D>
}
Ref<OccluderPolygon2D> TileSet::autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<OccluderPolygon2D>());
if (!tile_map[p_id].autotile_data.occluder_map.has(p_coord)) {
@@ -880,38 +846,32 @@ Ref<OccluderPolygon2D> TileSet::autotile_get_light_occluder(int p_id, const Vect
}
void TileSet::tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].navigation_polygon_offset = p_offset;
}
Vector2 TileSet::tile_get_navigation_polygon_offset(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].navigation_polygon_offset;
}
void TileSet::tile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].navigation_polygon = p_navigation_polygon;
}
Ref<NavigationPolygon> TileSet::tile_get_navigation_polygon(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<NavigationPolygon>());
return tile_map[p_id].navigation_polygon;
}
-const Map<Vector2, Ref<OccluderPolygon2D> > &TileSet::autotile_get_light_oclusion_map(int p_id) const {
-
- static Map<Vector2, Ref<OccluderPolygon2D> > dummy;
+const Map<Vector2, Ref<OccluderPolygon2D>> &TileSet::autotile_get_light_oclusion_map(int p_id) const {
+ static Map<Vector2, Ref<OccluderPolygon2D>> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.occluder_map;
}
void TileSet::autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
if (p_navigation_polygon.is_null()) {
if (tile_map[p_id].autotile_data.navpoly_map.has(p_coord)) {
@@ -923,7 +883,6 @@ void TileSet::autotile_set_navigation_polygon(int p_id, const Ref<NavigationPoly
}
Ref<NavigationPolygon> TileSet::autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<NavigationPolygon>());
if (!tile_map[p_id].autotile_data.navpoly_map.has(p_coord)) {
return Ref<NavigationPolygon>();
@@ -932,27 +891,23 @@ Ref<NavigationPolygon> TileSet::autotile_get_navigation_polygon(int p_id, const
}
}
-const Map<Vector2, Ref<NavigationPolygon> > &TileSet::autotile_get_navigation_map(int p_id) const {
-
- static Map<Vector2, Ref<NavigationPolygon> > dummy;
+const Map<Vector2, Ref<NavigationPolygon>> &TileSet::autotile_get_navigation_map(int p_id) const {
+ static Map<Vector2, Ref<NavigationPolygon>> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.navpoly_map;
}
void TileSet::tile_set_occluder_offset(int p_id, const Vector2 &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].occluder_offset = p_offset;
}
Vector2 TileSet::tile_get_occluder_offset(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].occluder_offset;
}
void TileSet::tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].shapes_data = p_shapes;
for (int i = 0; i < p_shapes.size(); i++) {
@@ -962,27 +917,23 @@ void TileSet::tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes) {
}
Vector<TileSet::ShapeData> TileSet::tile_get_shapes(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector<ShapeData>());
return tile_map[p_id].shapes_data;
}
int TileSet::tile_get_z_index(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
return tile_map[p_id].z_index;
}
void TileSet::tile_set_z_index(int p_id, int p_z_index) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].z_index = p_z_index;
emit_changed();
}
void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
Vector<ShapeData> shapes_data;
Transform2D default_transform = tile_get_shape_transform(p_id, 0);
@@ -993,7 +944,9 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
if (p_shapes[i].get_type() == Variant::OBJECT) {
Ref<Shape2D> shape = p_shapes[i];
- if (shape.is_null()) continue;
+ if (shape.is_null()) {
+ continue;
+ }
s.shape = shape;
s.shape_transform = default_transform;
@@ -1005,30 +958,35 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
if (d.has("shape") && d["shape"].get_type() == Variant::OBJECT) {
s.shape = d["shape"];
_decompose_convex_shape(s.shape);
- } else
+ } else {
continue;
+ }
- if (d.has("shape_transform") && d["shape_transform"].get_type() == Variant::TRANSFORM2D)
+ if (d.has("shape_transform") && d["shape_transform"].get_type() == Variant::TRANSFORM2D) {
s.shape_transform = d["shape_transform"];
- else if (d.has("shape_offset") && d["shape_offset"].get_type() == Variant::VECTOR2)
+ } else if (d.has("shape_offset") && d["shape_offset"].get_type() == Variant::VECTOR2) {
s.shape_transform = Transform2D(0, (Vector2)d["shape_offset"]);
- else
+ } else {
s.shape_transform = default_transform;
+ }
- if (d.has("one_way") && d["one_way"].get_type() == Variant::BOOL)
+ if (d.has("one_way") && d["one_way"].get_type() == Variant::BOOL) {
s.one_way_collision = d["one_way"];
- else
+ } else {
s.one_way_collision = default_one_way;
+ }
- if (d.has("one_way_margin") && d["one_way_margin"].is_num())
+ if (d.has("one_way_margin") && d["one_way_margin"].is_num()) {
s.one_way_collision_margin = d["one_way_margin"];
- else
+ } else {
s.one_way_collision_margin = 1.0;
+ }
- if (d.has("autotile_coord") && d["autotile_coord"].get_type() == Variant::VECTOR2)
+ if (d.has("autotile_coord") && d["autotile_coord"].get_type() == Variant::VECTOR2) {
s.autotile_coord = d["autotile_coord"];
- else
+ } else {
s.autotile_coord = default_autotile_coord;
+ }
} else {
ERR_CONTINUE_MSG(true, "Expected an array of objects or dictionaries for tile_set_shapes.");
@@ -1042,7 +1000,6 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
}
Array TileSet::_tile_get_shapes(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Array());
Array arr;
@@ -1061,7 +1018,6 @@ Array TileSet::_tile_get_shapes(int p_id) const {
}
Array TileSet::_get_tiles_ids() const {
-
Array arr;
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
@@ -1072,12 +1028,14 @@ Array TileSet::_get_tiles_ids() const {
}
void TileSet::_decompose_convex_shape(Ref<Shape2D> p_shape) {
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
Ref<ConvexPolygonShape2D> convex = p_shape;
- if (!convex.is_valid())
+ if (!convex.is_valid()) {
return;
- Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(convex->get_points());
+ }
+ Vector<Vector<Vector2>> decomp = Geometry2D::decompose_polygon_in_convex(convex->get_points());
if (decomp.size() > 1) {
Array sub_shapes;
for (int i = 0; i < decomp.size(); i++) {
@@ -1092,23 +1050,19 @@ void TileSet::_decompose_convex_shape(Ref<Shape2D> p_shape) {
}
void TileSet::get_tile_list(List<int> *p_tiles) const {
-
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
-
p_tiles->push_back(E->key());
}
}
bool TileSet::has_tile(int p_id) const {
-
return tile_map.has(p_id);
}
bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) {
-
if (p_drawn_id == p_neighbor_id) {
return true;
- } else if (get_script_instance() != NULL) {
+ } else if (get_script_instance() != nullptr) {
if (get_script_instance()->has_method("_is_tile_bound")) {
Variant ret = get_script_instance()->call("_is_tile_bound", p_drawn_id, p_neighbor_id);
if (ret.get_type() == Variant::BOOL) {
@@ -1120,7 +1074,6 @@ bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) {
}
void TileSet::remove_tile(int p_id) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map.erase(p_id);
_change_notify("");
@@ -1128,32 +1081,29 @@ void TileSet::remove_tile(int p_id) {
}
int TileSet::get_last_unused_tile_id() const {
-
- if (tile_map.size())
+ if (tile_map.size()) {
return tile_map.back()->key() + 1;
- else
+ } else {
return 0;
+ }
}
int TileSet::find_tile_by_name(const String &p_name) const {
-
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
-
- if (p_name == E->get().name)
+ if (p_name == E->get().name) {
return E->key();
+ }
}
return -1;
}
void TileSet::clear() {
-
tile_map.clear();
_change_notify("");
emit_changed();
}
void TileSet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile);
ClassDB::bind_method(D_METHOD("autotile_clear_bitmask_map", "id"), &TileSet::autotile_clear_bitmask_map);
ClassDB::bind_method(D_METHOD("autotile_set_icon_coordinate", "id", "coord"), &TileSet::autotile_set_icon_coordinate);
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index eab40ce467..78f34e46ce 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -34,13 +34,12 @@
#include "core/array.h"
#include "core/resource.h"
#include "scene/2d/light_occluder_2d.h"
-#include "scene/2d/navigation_polygon.h"
+#include "scene/2d/navigation_region_2d.h"
#include "scene/resources/convex_polygon_shape_2d.h"
#include "scene/resources/shape_2d.h"
#include "scene/resources/texture.h"
class TileSet : public Resource {
-
GDCLASS(TileSet, Resource);
public:
@@ -48,13 +47,10 @@ public:
Ref<Shape2D> shape;
Transform2D shape_transform;
Vector2 autotile_coord;
- bool one_way_collision;
- float one_way_collision_margin;
+ bool one_way_collision = false;
+ float one_way_collision_margin = 1.0;
- ShapeData() {
- one_way_collision = false;
- one_way_collision_margin = 1.0;
- }
+ ShapeData() {}
};
enum BitmaskMode {
@@ -92,30 +88,25 @@ public:
};
struct AutotileData {
- BitmaskMode bitmask_mode;
- Size2 size;
- int spacing;
- Vector2 icon_coord;
+ BitmaskMode bitmask_mode = BITMASK_2X2;
+ // Default size to prevent invalid value
+ Size2 size = Size2(64, 64);
+ Vector2 icon_coord = Vector2(0, 0);
+ int spacing = 0;
Map<Vector2, uint32_t> flags;
- Map<Vector2, Ref<OccluderPolygon2D> > occluder_map;
- Map<Vector2, Ref<NavigationPolygon> > navpoly_map;
+ Map<Vector2, Ref<OccluderPolygon2D>> occluder_map;
+ Map<Vector2, Ref<NavigationPolygon>> navpoly_map;
Map<Vector2, int> priority_map;
Map<Vector2, int> z_index_map;
- // Default size to prevent invalid value
- explicit AutotileData() :
- bitmask_mode(BITMASK_2X2),
- size(64, 64),
- spacing(0),
- icon_coord(0, 0) {}
+ explicit AutotileData() {}
};
private:
struct TileData {
-
String name;
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
Vector2 offset;
Rect2i region;
Vector<ShapeData> shapes_data;
@@ -124,16 +115,13 @@ private:
Vector2 navigation_polygon_offset;
Ref<NavigationPolygon> navigation_polygon;
Ref<ShaderMaterial> material;
- TileMode tile_mode;
- Color modulate;
+ TileMode tile_mode = SINGLE_TILE;
+ // Default modulate for back-compat
+ Color modulate = Color(1, 1, 1);
AutotileData autotile_data;
- int z_index;
+ int z_index = 0;
- // Default modulate for back-compat
- explicit TileData() :
- tile_mode(SINGLE_TILE),
- modulate(1, 1, 1),
- z_index(0) {}
+ explicit TileData() {}
};
Map<int, TileData> tile_map;
@@ -158,11 +146,11 @@ public:
void tile_set_name(int p_id, const String &p_name);
String tile_get_name(int p_id) const;
- void tile_set_texture(int p_id, const Ref<Texture> &p_texture);
- Ref<Texture> tile_get_texture(int p_id) const;
+ void tile_set_texture(int p_id, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> tile_get_texture(int p_id) const;
- void tile_set_normal_map(int p_id, const Ref<Texture> &p_normal_map);
- Ref<Texture> tile_get_normal_map(int p_id) const;
+ void tile_set_normal_map(int p_id, const Ref<Texture2D> &p_normal_map);
+ Ref<Texture2D> tile_get_normal_map(int p_id) const;
void tile_set_texture_offset(int p_id, const Vector2 &p_offset);
Vector2 tile_get_texture_offset(int p_id) const;
@@ -194,8 +182,8 @@ public:
void autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag);
uint32_t autotile_get_bitmask(int p_id, Vector2 p_coord);
const Map<Vector2, uint32_t> &autotile_get_bitmask_map(int p_id);
- Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = NULL, const Vector2 &p_tile_location = Vector2());
- Vector2 atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node = NULL, const Vector2 &p_tile_location = Vector2());
+ Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = nullptr, const Vector2 &p_tile_location = Vector2());
+ Vector2 atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node = nullptr, const Vector2 &p_tile_location = Vector2());
void tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape);
Ref<Shape2D> tile_get_shape(int p_id, int p_shape_id) const;
@@ -233,7 +221,7 @@ public:
void autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord);
Ref<OccluderPolygon2D> autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const;
- const Map<Vector2, Ref<OccluderPolygon2D> > &autotile_get_light_oclusion_map(int p_id) const;
+ const Map<Vector2, Ref<OccluderPolygon2D>> &autotile_get_light_oclusion_map(int p_id) const;
void tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset);
Vector2 tile_get_navigation_polygon_offset(int p_id) const;
@@ -243,7 +231,7 @@ public:
void autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord);
Ref<NavigationPolygon> autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const;
- const Map<Vector2, Ref<NavigationPolygon> > &autotile_get_navigation_map(int p_id) const;
+ const Map<Vector2, Ref<NavigationPolygon>> &autotile_get_navigation_map(int p_id) const;
void tile_set_z_index(int p_id, int p_z_index);
int tile_get_z_index(int p_id) const;
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 444bb698ae..379ba53a34 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -34,7 +34,6 @@
#include "scene/resources/texture.h"
class VideoStreamPlayback : public Resource {
-
GDCLASS(VideoStreamPlayback, Resource);
public:
@@ -58,7 +57,8 @@ public:
virtual void set_audio_track(int p_idx) = 0;
- virtual Ref<Texture> get_texture() const = 0;
+ virtual Ref<Texture2D> get_texture() const = 0;
+
virtual void update(float p_delta) = 0;
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) = 0;
@@ -67,7 +67,6 @@ public:
};
class VideoStream : public Resource {
-
GDCLASS(VideoStream, Resource);
OBJ_SAVE_TYPE(VideoStream); // Saves derived classes with common type so they can be interchanged.
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index b3a72ea7b6..b8d2003e68 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -31,19 +31,18 @@
#include "visual_shader.h"
#include "core/vmap.h"
-#include "servers/visual/shader_types.h"
+#include "servers/rendering/shader_types.h"
+#include "visual_shader_nodes.h"
bool VisualShaderNode::is_simple_decl() const {
return simple_decl;
}
void VisualShaderNode::set_output_port_for_preview(int p_index) {
-
port_preview = p_index;
}
int VisualShaderNode::get_output_port_for_preview() const {
-
return port_preview;
}
@@ -64,9 +63,56 @@ bool VisualShaderNode::is_port_separator(int p_index) const {
return false;
}
+bool VisualShaderNode::is_output_port_connected(int p_port) const {
+ if (connected_output_ports.has(p_port)) {
+ return connected_output_ports[p_port];
+ }
+ return false;
+}
+
+void VisualShaderNode::set_output_port_connected(int p_port, bool p_connected) {
+ if (p_connected) {
+ connected_output_ports[p_port] = true;
+ ++connected_output_count;
+ } else {
+ --connected_output_count;
+ if (connected_output_count == 0) {
+ connected_output_ports[p_port] = false;
+ }
+ }
+}
+
+bool VisualShaderNode::is_input_port_connected(int p_port) const {
+ if (connected_input_ports.has(p_port)) {
+ return connected_input_ports[p_port];
+ }
+ return false;
+}
+
+void VisualShaderNode::set_input_port_connected(int p_port, bool p_connected) {
+ connected_input_ports[p_port] = p_connected;
+}
+
+bool VisualShaderNode::is_generate_input_var(int p_port) const {
+ return true;
+}
+
+bool VisualShaderNode::is_code_generated() const {
+ return true;
+}
+
+bool VisualShaderNode::is_show_prop_names() const {
+ return false;
+}
+
+bool VisualShaderNode::is_use_prop_slots() const {
+ return false;
+}
+
Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
return Vector<VisualShader::DefaultTextureParam>();
}
+
String VisualShaderNode::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return String();
}
@@ -84,7 +130,6 @@ Vector<StringName> VisualShaderNode::get_editable_properties() const {
}
Array VisualShaderNode::get_default_input_values() const {
-
Array ret;
for (Map<int, Variant>::Element *E = default_input_values.front(); E; E = E->next()) {
ret.push_back(E->key());
@@ -92,8 +137,8 @@ Array VisualShaderNode::get_default_input_values() const {
}
return ret;
}
-void VisualShaderNode::set_default_input_values(const Array &p_values) {
+void VisualShaderNode::set_default_input_values(const Array &p_values) {
if (p_values.size() % 2 == 0) {
for (int i = 0; i < p_values.size(); i += 2) {
default_input_values[p_values[i + 0]] = p_values[i + 1];
@@ -112,7 +157,6 @@ String VisualShaderNode::get_input_port_default_hint(int p_port) const {
}
void VisualShaderNode::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_output_port_for_preview", "port"), &VisualShaderNode::set_output_port_for_preview);
ClassDB::bind_method(D_METHOD("get_output_port_for_preview"), &VisualShaderNode::get_output_port_for_preview);
@@ -127,6 +171,7 @@ void VisualShaderNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("editor_refresh_request"));
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT);
BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR);
BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN);
BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM);
@@ -135,8 +180,6 @@ void VisualShaderNode::_bind_methods() {
}
VisualShaderNode::VisualShaderNode() {
- port_preview = -1;
- simple_decl = true;
}
/////////////////////////////////////////////////////////
@@ -223,7 +266,6 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
}
String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
ERR_FAIL_COND_V(!get_script_instance(), "");
ERR_FAIL_COND_V(!get_script_instance()->has_method("_get_code"), "");
Array input_vars;
@@ -262,20 +304,19 @@ String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, Vis
}
void VisualShaderNodeCustom::_bind_methods() {
-
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_subcategory"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_input_port_name", PropertyInfo(Variant::INT, "port")));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_count"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_type", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_highend"));
}
VisualShaderNodeCustom::VisualShaderNodeCustom() {
@@ -284,6 +325,57 @@ VisualShaderNodeCustom::VisualShaderNodeCustom() {
/////////////////////////////////////////////////////////
+void VisualShader::set_shader_type(Type p_type) {
+ current_type = p_type;
+}
+
+VisualShader::Type VisualShader::get_shader_type() const {
+ return current_type;
+}
+
+void VisualShader::set_version(const String &p_version) {
+ version = p_version;
+}
+
+String VisualShader::get_version() const {
+ return version;
+}
+
+void VisualShader::update_version(const String &p_new_version) {
+ if (version == "") {
+ for (int i = 0; i < TYPE_MAX; i++) {
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr());
+ if (expression.is_valid()) {
+ for (int j = 0; j < expression->get_input_port_count(); j++) {
+ int type = expression->get_input_port_type(j);
+ if (type > 0) { // + PORT_TYPE_SCALAR_INT
+ type += 1;
+ }
+ expression->set_input_port_type(j, type);
+ }
+ for (int j = 0; j < expression->get_output_port_count(); j++) {
+ int type = expression->get_output_port_type(j);
+ if (type > 0) { // + PORT_TYPE_SCALAR_INT
+ type += 1;
+ }
+ expression->set_output_port_type(j, type);
+ }
+ }
+ Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E->get().node.ptr());
+ if (compare.is_valid()) {
+ int ctype = int(compare->get_comparison_type());
+ if (int(ctype) > 0) { // + PORT_TYPE_SCALAR_INT
+ ctype += 1;
+ }
+ compare->set_comparison_type(VisualShaderNodeCompare::ComparisonType(ctype));
+ }
+ }
+ }
+ }
+ set_version(p_new_version);
+}
+
void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) {
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_id < 2);
@@ -304,10 +396,10 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co
if (input.is_valid()) {
input->shader_mode = shader_mode;
input->shader_type = p_type;
- input->connect("input_type_changed", this, "_input_type_changed", varray(p_type, p_id));
+ input->connect("input_type_changed", callable_mp(this, &VisualShader::_input_type_changed), varray(p_type, p_id));
}
- n.node->connect("changed", this, "_queue_update");
+ n.node->connect("changed", callable_mp(this, &VisualShader::_queue_update));
Ref<VisualShaderNodeCustom> custom = n.node;
if (custom.is_valid()) {
@@ -351,6 +443,7 @@ Vector<int> VisualShader::get_node_list(Type p_type) const {
return ret;
}
+
int VisualShader::get_valid_node_id(Type p_type) const {
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, NODE_ID_INVALID);
const Graph *g = &graph[p_type];
@@ -359,8 +452,9 @@ int VisualShader::get_valid_node_id(Type p_type) const {
int VisualShader::find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const {
for (const Map<int, Node>::Element *E = graph[p_type].nodes.front(); E; E = E->next()) {
- if (E->get().node == p_node)
+ if (E->get().node == p_node) {
return E->key();
+ }
}
return NODE_ID_INVALID;
@@ -374,10 +468,10 @@ void VisualShader::remove_node(Type p_type, int p_id) {
Ref<VisualShaderNodeInput> input = g->nodes[p_id].node;
if (input.is_valid()) {
- input->disconnect("input_type_changed", this, "_input_type_changed");
+ input->disconnect("input_type_changed", callable_mp(this, &VisualShader::_input_type_changed));
}
- g->nodes[p_id].node->disconnect("changed", this, "_queue_update");
+ g->nodes[p_id].node->disconnect("changed", callable_mp(this, &VisualShader::_queue_update));
g->nodes.erase(p_id);
@@ -387,6 +481,7 @@ void VisualShader::remove_node(Type p_type, int p_id) {
g->connections.erase(E);
if (E->get().from_node == p_id) {
g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
+ g->nodes[E->get().to_node].node->set_input_port_connected(E->get().to_port, false);
}
}
E = N;
@@ -400,7 +495,6 @@ bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_p
const Graph *g = &graph[p_type];
for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
return true;
}
@@ -415,7 +509,6 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod
const VisualShader::Node &node = p_graph->nodes[p_node];
for (const List<int>::Element *E = node.prev_connected_nodes.front(); E; E = E->next()) {
-
if (E->get() == p_target) {
return true;
}
@@ -429,24 +522,28 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod
}
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
-
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
const Graph *g = &graph[p_type];
- if (!g->nodes.has(p_from_node))
+ if (!g->nodes.has(p_from_node)) {
return false;
+ }
- if (p_from_node == p_to_node)
+ if (p_from_node == p_to_node) {
return false;
+ }
- if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_output_port_count())
+ if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_output_port_count()) {
return false;
+ }
- if (!g->nodes.has(p_to_node))
+ if (!g->nodes.has(p_to_node)) {
return false;
+ }
- if (p_to_port < 0 || p_to_port >= g->nodes[p_to_node].node->get_input_port_count())
+ if (p_to_port < 0 || p_to_port >= g->nodes[p_to_node].node->get_input_port_count()) {
return false;
+ }
VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
@@ -456,20 +553,20 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
}
for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
return false;
}
}
- if (is_nodes_connected_relatively(g, p_from_node, p_to_node))
+ if (is_nodes_connected_relatively(g, p_from_node, p_to_node)) {
return false;
+ }
return true;
}
bool VisualShader::is_port_types_compatible(int p_a, int p_b) const {
- return MAX(0, p_a - 2) == (MAX(0, p_b - 2));
+ return MAX(0, p_a - 3) == (MAX(0, p_b - 3));
}
void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
@@ -482,6 +579,8 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from
c.to_port = p_to_port;
g->connections.push_back(c);
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
+ g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true);
+ g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
_queue_update();
}
@@ -501,7 +600,6 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform.");
for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
ERR_FAIL_V(ERR_ALREADY_EXISTS);
}
@@ -514,6 +612,8 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
c.to_port = p_to_port;
g->connections.push_back(c);
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
+ g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true);
+ g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
_queue_update();
return OK;
@@ -524,10 +624,11 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
Graph *g = &graph[p_type];
for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
g->connections.erase(E);
g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
+ g->nodes[p_from_node].node->set_output_port_connected(p_from_port, false);
+ g->nodes[p_to_node].node->set_input_port_connected(p_to_port, false);
_queue_update();
return;
}
@@ -570,9 +671,7 @@ void VisualShader::set_mode(Mode p_mode) {
flags.clear();
shader_mode = p_mode;
for (int i = 0; i < TYPE_MAX; i++) {
-
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
-
Ref<VisualShaderNodeInput> input = E->get().node;
if (input.is_valid()) {
input->shader_mode = shader_mode;
@@ -585,7 +684,6 @@ void VisualShader::set_mode(Mode p_mode) {
// clear connections since they are no longer valid
for (List<Connection>::Element *E = graph[i].connections.front(); E;) {
-
bool keep = true;
List<Connection>::Element *N = E->next();
@@ -639,7 +737,6 @@ bool VisualShader::is_text_shader() const {
}
String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &default_tex_params) const {
-
Ref<VisualShaderNode> node = get_node(p_type, p_node);
ERR_FAIL_COND_V(!node.is_valid(), String());
ERR_FAIL_COND_V(p_port < 0 || p_port >= node->get_output_port_count(), String());
@@ -658,7 +755,6 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
if (global_expression.is_valid()) {
-
String expr = "";
expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
expr += global_expression->generate_global(get_mode(), Type(i), -1);
@@ -697,9 +793,11 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
ERR_FAIL_COND_V(err != OK, String());
if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) {
- code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
+ code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
+ } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ code += "\tCOLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n";
} else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_BOOLEAN) {
- code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0 );\n";
+ code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n";
} else {
code += "\tCOLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n";
}
@@ -725,7 +823,6 @@ String VisualShader::validate_port_name(const String &p_name, const List<String>
}
if (name != String()) {
-
String valid_name;
for (int i = 0; i < name.length(); i++) {
@@ -766,13 +863,11 @@ String VisualShader::validate_port_name(const String &p_name, const List<String>
}
String VisualShader::validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const {
-
String name = p_name; //validate name first
while (name.length() && !IS_INITIAL_CHAR(name[0])) {
name = name.substr(1, name.length() - 1);
}
if (name != String()) {
-
String valid_name;
for (int i = 0; i < name.length(); i++) {
@@ -793,7 +888,6 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua
int attempt = 1;
while (true) {
-
bool exists = false;
for (int i = 0; i < TYPE_MAX; i++) {
for (const Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
@@ -834,16 +928,19 @@ VisualShader::RenderModeEnums VisualShader::render_mode_enums[] = {
{ Shader::MODE_SPATIAL, "diffuse" },
{ Shader::MODE_SPATIAL, "specular" },
{ Shader::MODE_CANVAS_ITEM, "blend" },
- { Shader::MODE_CANVAS_ITEM, NULL }
+ { Shader::MODE_CANVAS_ITEM, nullptr }
};
static const char *type_string[VisualShader::TYPE_MAX] = {
"vertex",
"fragment",
- "light"
+ "light",
+ "emit",
+ "process",
+ "end"
};
-bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
+bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
if (name == "mode") {
set_mode(Shader::Mode(int(p_value)));
@@ -880,7 +977,6 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
String index = name.get_slicec('/', 2);
if (index == "connections") {
-
Vector<int> conns = p_value;
if (conns.size() % 4 == 0) {
for (int i = 0; i < conns.size(); i += 4) {
@@ -917,7 +1013,6 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
}
bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name == "mode") {
r_ret = get_mode();
@@ -946,7 +1041,6 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
String index = name.get_slicec('/', 2);
if (index == "connections") {
-
Vector<int> conns;
for (const List<Connection>::Element *E = graph[type].connections.front(); E; E = E->next()) {
conns.push_back(E->get().from_node);
@@ -984,18 +1078,17 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
}
return false;
}
-void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
+void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
//mode
- p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Spatial,CanvasItem,Particles"));
+ p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Node3D,CanvasItem,Particles,Sky"));
//render modes
Map<String, String> blend_mode_enums;
Set<String> toggles;
- for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) {
-
- String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i];
+ for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) {
+ String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i];
int idx = 0;
bool in_enum = false;
while (render_mode_enums[idx].string) {
@@ -1019,7 +1112,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (Map<String, String>::Element *E = blend_mode_enums.front(); E; E = E->next()) {
-
p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E->key(), PROPERTY_HINT_ENUM, E->get()));
}
@@ -1029,32 +1121,29 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < TYPE_MAX; i++) {
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
-
String prop_name = "nodes/";
prop_name += type_string[i];
prop_name += "/" + itos(E->key());
if (E->key() != NODE_ID_OUTPUT) {
-
p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
}
p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- if (Object::cast_to<VisualShaderNodeGroupBase>(E->get().node.ptr()) != NULL) {
+ if (Object::cast_to<VisualShaderNodeGroupBase>(E->get().node.ptr()) != nullptr) {
p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/input_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/output_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
- if (Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr()) != NULL) {
+ if (Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr()) != nullptr) {
p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
- p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "nodes/" + String(type_string[i]) + "/connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "nodes/" + String(type_string[i]) + "/connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const {
-
const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node;
//check inputs recursively first
@@ -1071,13 +1160,46 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
Error err = _write_node(type, global_code, global_code_per_node, global_code_per_func, code, def_tex_params, input_connections, output_connections, from_node, processed, for_preview, r_classes);
- if (err)
+ if (err) {
return err;
+ }
}
}
// then this node
+ Vector<VisualShader::DefaultTextureParam> params = vsnode->get_default_texture_parameters(type, node);
+ for (int i = 0; i < params.size(); i++) {
+ def_tex_params.push_back(params[i]);
+ }
+
+ Ref<VisualShaderNodeInput> input = vsnode;
+ bool skip_global = input.is_valid() && for_preview;
+
+ if (!skip_global) {
+ Ref<VisualShaderNodeUniform> uniform = vsnode;
+ if (!uniform.is_valid() || !uniform->is_global_code_generated()) {
+ global_code += vsnode->generate_global(get_mode(), type, node);
+ }
+
+ String class_name = vsnode->get_class_name();
+ if (class_name == "VisualShaderNodeCustom") {
+ class_name = vsnode->get_script_instance()->get_script()->get_path();
+ }
+ if (!r_classes.has(class_name)) {
+ global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node);
+ for (int i = 0; i < TYPE_MAX; i++) {
+ global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node);
+ }
+ r_classes.insert(class_name);
+ }
+ }
+
+ if (!vsnode->is_code_generated()) { // just generate globals and ignore locals
+ processed.insert(node);
+ return OK;
+ }
+
code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n";
Vector<String> input_vars;
@@ -1112,24 +1234,43 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
inputs[i] = src_var;
} else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
inputs[i] = "dot(" + src_var + ", vec3(0.333333, 0.333333, 0.333333))";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
+ inputs[i] = "dot(float(" + src_var + "), vec3(0.333333, 0.333333, 0.333333))";
} else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = "vec3(" + src_var + ")";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ inputs[i] = "vec3(float(" + src_var + "))";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
inputs[i] = "all(bvec3(" + src_var + "))";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = src_var + " > 0.0 ? true : false";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ inputs[i] = src_var + " > 0 ? true : false";
} else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
inputs[i] = src_var + " ? 1.0 : 0.0";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
+ inputs[i] = src_var + " ? 1 : 0";
} else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
inputs[i] = "vec3(" + src_var + " ? 1.0 : 0.0)";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ inputs[i] = "float(" + src_var + ")";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
+ inputs[i] = "int(" + src_var + ")";
}
} else {
+ if (!vsnode->is_generate_input_var(i)) {
+ continue;
+ }
Variant defval = vsnode->get_input_port_default_value(i);
- if (defval.get_type() == Variant::REAL || defval.get_type() == Variant::INT) {
+ if (defval.get_type() == Variant::FLOAT) {
float val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n";
+ } else if (defval.get_type() == Variant::INT) {
+ int val = defval;
+ inputs[i] = "n_in" + itos(node) + "p" + itos(i);
+ code += "\tint " + inputs[i] + " = " + itos(val) + ";\n";
} else if (defval.get_type() == Variant::BOOL) {
bool val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
@@ -1168,10 +1309,21 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
for (int i = 0; i < output_count; i++) {
String var_name = "n_out" + itos(node) + "p" + itos(i);
switch (vsnode->get_output_port_type(i)) {
- case VisualShaderNode::PORT_TYPE_SCALAR: outputs[i] = "float " + var_name; break;
- case VisualShaderNode::PORT_TYPE_VECTOR: outputs[i] = "vec3 " + var_name; break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN: outputs[i] = "bool " + var_name; break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM: outputs[i] = "mat4 " + var_name; break;
+ case VisualShaderNode::PORT_TYPE_SCALAR:
+ outputs[i] = "float " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT:
+ outputs[i] = "int " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_VECTOR:
+ outputs[i] = "vec3 " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN:
+ outputs[i] = "bool " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM:
+ outputs[i] = "mat4 " + var_name;
+ break;
default: {
}
}
@@ -1181,52 +1333,52 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
for (int i = 0; i < output_count; i++) {
outputs[i] = "n_out" + itos(node) + "p" + itos(i);
switch (vsnode->get_output_port_type(i)) {
- case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break;
- case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN: code += String() + "\tbool " + outputs[i] + ";\n"; break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break;
+ case VisualShaderNode::PORT_TYPE_SCALAR:
+ code += String() + "\tfloat " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT:
+ code += String() + "\tint " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_VECTOR:
+ code += String() + "\tvec3 " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN:
+ code += String() + "\tbool " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM:
+ code += String() + "\tmat4 " + outputs[i] + ";\n";
+ break;
default: {
}
}
}
}
- Vector<VisualShader::DefaultTextureParam> params = vsnode->get_default_texture_parameters(type, node);
- for (int i = 0; i < params.size(); i++) {
- def_tex_params.push_back(params[i]);
- }
-
- Ref<VisualShaderNodeInput> input = vsnode;
- bool skip_global = input.is_valid() && for_preview;
+ code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
- if (!skip_global) {
+ code += "\n"; //
+ processed.insert(node);
- global_code += vsnode->generate_global(get_mode(), type, node);
+ return OK;
+}
- String class_name = vsnode->get_class_name();
- if (class_name == "VisualShaderNodeCustom") {
- class_name = vsnode->get_script_instance()->get_script()->get_language()->get_global_class_name(vsnode->get_script_instance()->get_script()->get_path());
- }
- if (!r_classes.has(class_name)) {
- global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node);
- for (int i = 0; i < TYPE_MAX; i++) {
- global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node);
+bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const {
+ if (!ShaderTypes::get_singleton()->get_functions(p_mode).has(p_func_name)) {
+ if (p_mode == RenderingServer::ShaderMode::SHADER_PARTICLES) {
+ if (p_func_name == "emit" || p_func_name == "process" || p_func_name == "end") {
+ return true;
}
- r_classes.insert(class_name);
}
+ return false;
}
- code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
-
- code += "\n"; //
- processed.insert(node);
-
- return OK;
+ return true;
}
void VisualShader::_update_shader() const {
- if (!dirty)
+ if (!dirty) {
return;
+ }
dirty = false;
@@ -1236,8 +1388,8 @@ void VisualShader::_update_shader() const {
StringBuilder code;
Vector<VisualShader::DefaultTextureParam> default_tex_params;
Set<StringName> classes;
- List<int> insertion_pos;
- static const char *shader_mode_str[Shader::MODE_MAX] = { "spatial", "canvas_item", "particles" };
+ Map<int, int> insertion_pos;
+ static const char *shader_mode_str[Shader::MODE_MAX] = { "spatial", "canvas_item", "particles", "sky" };
global_code += String() + "shader_type " + shader_mode_str[shader_mode] + ";\n";
@@ -1246,16 +1398,22 @@ void VisualShader::_update_shader() const {
{
//fill render mode enums
int idx = 0;
+ bool specular = false;
while (render_mode_enums[idx].string) {
-
if (shader_mode == render_mode_enums[idx].mode) {
-
- if (modes.has(render_mode_enums[idx].string)) {
-
- int which = modes[render_mode_enums[idx].string];
+ if (shader_mode == Shader::MODE_SPATIAL) {
+ if (String(render_mode_enums[idx].string) == "specular") {
+ specular = true;
+ }
+ }
+ if (modes.has(render_mode_enums[idx].string) || specular) {
+ int which = 0;
+ if (modes.has(render_mode_enums[idx].string)) {
+ which = modes[render_mode_enums[idx].string];
+ }
int count = 0;
- for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) {
- String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i];
+ for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) {
+ String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i];
if (mode.begins_with(render_mode_enums[idx].string)) {
if (count == which) {
if (render_mode != String()) {
@@ -1273,9 +1431,8 @@ void VisualShader::_update_shader() const {
}
//fill render mode flags
- for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) {
-
- String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i];
+ for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) {
+ String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i];
if (flags.has(mode)) {
if (render_mode != String()) {
render_mode += ", ";
@@ -1286,18 +1443,23 @@ void VisualShader::_update_shader() const {
}
if (render_mode != String()) {
-
global_code += "render_mode " + render_mode + ";\n\n";
}
- static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light" };
+ static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "emit", "process", "end" };
String global_expressions;
+ Set<String> used_uniform_names;
+ List<VisualShaderNodeUniform *> uniforms;
+
for (int i = 0, index = 0; i < TYPE_MAX; i++) {
+ if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
+ continue;
+ }
+
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
if (global_expression.is_valid()) {
-
String expr = "";
expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
expr += global_expression->generate_global(get_mode(), Type(i), -1);
@@ -1305,15 +1467,40 @@ void VisualShader::_update_shader() const {
expr += "\n";
global_expressions += expr;
}
+ Ref<VisualShaderNodeUniformRef> uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(E->get().node.ptr());
+ if (uniform_ref.is_valid()) {
+ used_uniform_names.insert(uniform_ref->get_uniform_name());
+ }
+ Ref<VisualShaderNodeUniform> uniform = Object::cast_to<VisualShaderNodeUniform>(E->get().node.ptr());
+ if (uniform.is_valid()) {
+ uniforms.push_back(uniform.ptr());
+ }
}
}
+ for (int i = 0; i < uniforms.size(); i++) {
+ VisualShaderNodeUniform *uniform = uniforms[i];
+ if (used_uniform_names.has(uniform->get_uniform_name())) {
+ global_code += uniform->generate_global(get_mode(), Type(i), -1);
+ const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(true);
+ } else {
+ const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(false);
+ }
+ }
+
+ Map<int, String> code_map;
+
for (int i = 0; i < TYPE_MAX; i++) {
+ if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
+ continue;
+ }
//make it faster to go around through shader
VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
+ StringBuilder func_code;
+
for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) {
ConnectionKey from_key;
from_key.node = E->get().from_node;
@@ -1327,14 +1514,30 @@ void VisualShader::_update_shader() const {
input_connections.insert(to_key, E);
}
-
- code += "\nvoid " + String(func_name[i]) + "() {\n";
+ if (shader_mode != Shader::MODE_PARTICLES) {
+ func_code += "\nvoid " + String(func_name[i]) + "() {\n";
+ }
+ insertion_pos.insert(i, code.get_string_length() + func_code.get_string_length());
Set<int> processed;
- Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes);
+ Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes);
ERR_FAIL_COND(err != OK);
- insertion_pos.push_back(code.get_string_length());
+ if (shader_mode == Shader::MODE_PARTICLES) {
+ code_map.insert(i, func_code);
+ } else {
+ func_code += "}\n";
+ code += func_code;
+ }
+ }
+
+ if (shader_mode == Shader::MODE_PARTICLES) {
+ code += "\nvoid compute() {\n";
+ code += "\tif (RESTART) {\n";
+ code += code_map[TYPE_EMIT];
+ code += "\t} else {\n";
+ code += code_map[TYPE_PROCESS];
+ code += "\t}\n";
code += "}\n";
}
@@ -1345,6 +1548,9 @@ void VisualShader::_update_shader() const {
final_code += global_expressions;
String tcode = code;
for (int i = 0; i < TYPE_MAX; i++) {
+ if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
+ continue;
+ }
tcode = tcode.insert(insertion_pos[i], global_code_per_func[Type(i)]);
}
final_code += tcode;
@@ -1388,7 +1594,6 @@ void VisualShader::rebuild() {
}
void VisualShader::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VisualShader::set_mode);
ClassDB::bind_method(D_METHOD("add_node", "type", "node", "position", "id"), &VisualShader::add_node);
@@ -1403,7 +1608,7 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_node", "type", "id"), &VisualShader::remove_node);
ClassDB::bind_method(D_METHOD("is_node_connection", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection);
- ClassDB::bind_method(D_METHOD("can_connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection);
+ ClassDB::bind_method(D_METHOD("can_connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::can_connect_nodes);
ClassDB::bind_method(D_METHOD("connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::connect_nodes);
ClassDB::bind_method(D_METHOD("disconnect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::disconnect_nodes);
@@ -1411,19 +1616,25 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_node_connections", "type"), &VisualShader::_get_node_connections);
+ ClassDB::bind_method(D_METHOD("set_version", "version"), &VisualShader::set_version);
+ ClassDB::bind_method(D_METHOD("get_version"), &VisualShader::get_version);
+
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &VisualShader::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &VisualShader::get_graph_offset);
- ClassDB::bind_method(D_METHOD("_queue_update"), &VisualShader::_queue_update);
ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader);
- ClassDB::bind_method(D_METHOD("_input_type_changed"), &VisualShader::_input_type_changed);
-
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_version", "get_version");
+
+ ADD_PROPERTY_DEFAULT("code", ""); // Inherited from Shader, prevents showing default code as override in docs.
BIND_ENUM_CONSTANT(TYPE_VERTEX);
BIND_ENUM_CONSTANT(TYPE_FRAGMENT);
BIND_ENUM_CONSTANT(TYPE_LIGHT);
+ BIND_ENUM_CONSTANT(TYPE_EMIT);
+ BIND_ENUM_CONSTANT(TYPE_PROCESS);
+ BIND_ENUM_CONSTANT(TYPE_END);
BIND_ENUM_CONSTANT(TYPE_MAX);
BIND_CONSTANT(NODE_ID_INVALID);
@@ -1431,8 +1642,6 @@ void VisualShader::_bind_methods() {
}
VisualShader::VisualShader() {
- shader_mode = Shader::MODE_SPATIAL;
-
for (int i = 0; i < TYPE_MAX; i++) {
Ref<VisualShaderNodeOutput> output;
output.instance();
@@ -1441,8 +1650,6 @@ VisualShader::VisualShader() {
graph[i].nodes[NODE_ID_OUTPUT].node = output;
graph[i].nodes[NODE_ID_OUTPUT].position = Vector2(400, 150);
}
-
- dirty = true;
}
///////////////////////////////////////////////////////////
@@ -1554,32 +1761,94 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vec", "vec3(LIGHT_VEC, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_height", "LIGHT_HEIGHT" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR.rgb" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_alpha", "LIGHT_COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT_COLOR.a" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "shadow_alpha", "SHADOW_COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_vec", "vec3(SHADOW_VEC, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" },
- // Particles, Vertex
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
-
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "index", "float(INDEX)" },
-
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
- { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, NULL, NULL },
+ // Particles, Emit
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+
+ // Particles, Process
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+
+ // Particles, End
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+
+ // Sky, Fragment
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_cubemap_pass", "AT_CUBEMAP_PASS" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_half_res_pass", "AT_HALF_RES_PASS" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_quarter_res_pass", "AT_QUARTER_RES_PASS" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "eyedir", "EYEDIR" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "half_res_color", "HALF_RES_COLOR.rgb" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "half_res_alpha", "HALF_RES_COLOR.a" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light0_color", "LIGHT0_COLOR" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light0_direction", "LIGHT0_DIRECTION" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "light0_enabled", "LIGHT0_ENABLED" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light0_energy", "LIGHT0_ENERGY" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light1_color", "LIGHT1_COLOR" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light1_direction", "LIGHT1_DIRECTION" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "light1_enabled", "LIGHT1_ENABLED" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light1_energy", "LIGHT1_ENERGY" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light2_color", "LIGHT2_COLOR" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light2_direction", "LIGHT2_DIRECTION" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "light2_enabled", "LIGHT2_ENABLED" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light2_energy", "LIGHT2_ENERGY" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light3_color", "LIGHT3_COLOR" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light3_direction", "LIGHT3_DIRECTION" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "light3_enabled", "LIGHT3_ENABLED" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light3_energy", "LIGHT3_ENERGY" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "position", "POSITION" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "quarter_res_color", "QUARTER_RES_COLOR.rgb" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "quarter_res_alpha", "QUARTER_RES_COLOR.a" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "radiance", "RADIANCE" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "sky_coords", "vec3(SKY_COORDS, 0.0)" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+
+ { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, nullptr, nullptr },
};
const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
@@ -1628,30 +1897,29 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "vec3(0.0, 0.0, 1.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
- { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, NULL, NULL },
+ { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, nullptr, nullptr },
};
int VisualShaderNodeInput::get_input_port_count() const {
-
return 0;
}
-VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_port_type(int p_port) const {
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeInput::get_input_port_name(int p_port) const {
+String VisualShaderNodeInput::get_input_port_name(int p_port) const {
return "";
}
int VisualShaderNodeInput::get_output_port_count() const {
-
return 1;
}
-VisualShaderNodeInput::PortType VisualShaderNodeInput::get_output_port_type(int p_port) const {
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_output_port_type(int p_port) const {
return get_input_type_by_name(input_name);
}
+
String VisualShaderNodeInput::get_output_port_name(int p_port) const {
return "";
}
@@ -1661,7 +1929,6 @@ String VisualShaderNodeInput::get_caption() const {
}
String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
if (get_output_port_type(0) == PORT_TYPE_SAMPLER) {
return "";
}
@@ -1683,17 +1950,20 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
switch (get_output_port_type(0)) {
case PORT_TYPE_SCALAR: {
code = "\t" + p_output_vars[0] + " = 0.0;\n";
- } break; //default (none found) is scalar
+ } break;
+ case PORT_TYPE_SCALAR_INT: {
+ code = "\t" + p_output_vars[0] + " = 0;\n";
+ } break;
case PORT_TYPE_VECTOR: {
code = "\t" + p_output_vars[0] + " = vec3(0.0);\n";
- } break; //default (none found) is scalar
+ } break;
case PORT_TYPE_TRANSFORM: {
code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n";
- } break; //default (none found) is scalar
+ } break;
case PORT_TYPE_BOOLEAN: {
code = "\t" + p_output_vars[0] + " = false;\n";
} break;
- default:
+ default: //default (none found) is scalar
break;
}
}
@@ -1735,7 +2005,6 @@ String VisualShaderNodeInput::get_input_name() const {
}
String VisualShaderNodeInput::get_input_real_name() const {
-
int idx = 0;
while (ports[idx].mode != Shader::MODE_MAX) {
@@ -1749,7 +2018,6 @@ String VisualShaderNodeInput::get_input_real_name() const {
}
VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_type_by_name(String p_name) const {
-
int idx = 0;
while (ports[idx].mode != Shader::MODE_MAX) {
@@ -1811,7 +2079,6 @@ String VisualShaderNodeInput::get_input_index_name(int p_index) const {
}
void VisualShaderNodeInput::_validate_property(PropertyInfo &property) const {
-
if (property.name == "input_name") {
String port_list;
@@ -1841,19 +2108,227 @@ Vector<StringName> VisualShaderNodeInput::get_editable_properties() const {
}
void VisualShaderNodeInput::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_input_name", "name"), &VisualShaderNodeInput::set_input_name);
ClassDB::bind_method(D_METHOD("get_input_name"), &VisualShaderNodeInput::get_input_name);
ClassDB::bind_method(D_METHOD("get_input_real_name"), &VisualShaderNodeInput::get_input_real_name);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name");
ADD_SIGNAL(MethodInfo("input_type_changed"));
}
+
VisualShaderNodeInput::VisualShaderNodeInput() {
- input_name = "[None]";
- // changed when set
- shader_type = VisualShader::TYPE_MAX;
- shader_mode = Shader::MODE_MAX;
+}
+
+////////////// UniformRef
+
+List<VisualShaderNodeUniformRef::Uniform> uniforms;
+
+void VisualShaderNodeUniformRef::add_uniform(const String &p_name, UniformType p_type) {
+ uniforms.push_back({ p_name, p_type });
+}
+
+void VisualShaderNodeUniformRef::clear_uniforms() {
+ uniforms.clear();
+}
+
+bool VisualShaderNodeUniformRef::has_uniform(const String &p_name) {
+ for (List<VisualShaderNodeUniformRef::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().name == p_name) {
+ return true;
+ }
+ }
+ return false;
+}
+
+String VisualShaderNodeUniformRef::get_caption() const {
+ return "UniformRef";
+}
+
+int VisualShaderNodeUniformRef::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_input_port_type(int p_port) const {
+ return PortType::PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeUniformRef::get_input_port_name(int p_port) const {
+ return "";
+}
+
+int VisualShaderNodeUniformRef::get_output_port_count() const {
+ switch (uniform_type) {
+ case UniformType::UNIFORM_TYPE_FLOAT:
+ return 1;
+ case UniformType::UNIFORM_TYPE_INT:
+ return 1;
+ case UniformType::UNIFORM_TYPE_BOOLEAN:
+ return 1;
+ case UniformType::UNIFORM_TYPE_VECTOR:
+ return 1;
+ case UniformType::UNIFORM_TYPE_TRANSFORM:
+ return 1;
+ case UniformType::UNIFORM_TYPE_COLOR:
+ return 2;
+ case UniformType::UNIFORM_TYPE_SAMPLER:
+ return 1;
+ default:
+ break;
+ }
+ return 1;
+}
+
+VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port_type(int p_port) const {
+ switch (uniform_type) {
+ case UniformType::UNIFORM_TYPE_FLOAT:
+ return PortType::PORT_TYPE_SCALAR;
+ case UniformType::UNIFORM_TYPE_INT:
+ return PortType::PORT_TYPE_SCALAR_INT;
+ case UniformType::UNIFORM_TYPE_BOOLEAN:
+ return PortType::PORT_TYPE_BOOLEAN;
+ case UniformType::UNIFORM_TYPE_VECTOR:
+ return PortType::PORT_TYPE_VECTOR;
+ case UniformType::UNIFORM_TYPE_TRANSFORM:
+ return PortType::PORT_TYPE_TRANSFORM;
+ case UniformType::UNIFORM_TYPE_COLOR:
+ if (p_port == 0) {
+ return PortType::PORT_TYPE_VECTOR;
+ } else if (p_port == 1) {
+ return PORT_TYPE_SCALAR;
+ }
+ break;
+ case UniformType::UNIFORM_TYPE_SAMPLER:
+ return PortType::PORT_TYPE_SAMPLER;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const {
+ switch (uniform_type) {
+ case UniformType::UNIFORM_TYPE_FLOAT:
+ return "";
+ case UniformType::UNIFORM_TYPE_INT:
+ return "";
+ case UniformType::UNIFORM_TYPE_BOOLEAN:
+ return "";
+ case UniformType::UNIFORM_TYPE_VECTOR:
+ return "";
+ case UniformType::UNIFORM_TYPE_TRANSFORM:
+ return "";
+ case UniformType::UNIFORM_TYPE_COLOR:
+ if (p_port == 0) {
+ return "rgb";
+ } else if (p_port == 1) {
+ return "alpha";
+ }
+ break;
+ case UniformType::UNIFORM_TYPE_SAMPLER:
+ return "";
+ break;
+ default:
+ break;
+ }
+ return "";
+}
+
+void VisualShaderNodeUniformRef::set_uniform_name(const String &p_name) {
+ uniform_name = p_name;
+ if (uniform_name != "[None]") {
+ uniform_type = get_uniform_type_by_name(uniform_name);
+ } else {
+ uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
+ }
+ emit_changed();
+}
+
+String VisualShaderNodeUniformRef::get_uniform_name() const {
+ return uniform_name;
+}
+
+int VisualShaderNodeUniformRef::get_uniforms_count() const {
+ return uniforms.size();
+}
+
+String VisualShaderNodeUniformRef::get_uniform_name_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < uniforms.size()) {
+ return uniforms[p_idx].name;
+ }
+ return "";
+}
+
+VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_name(const String &p_name) const {
+ for (int i = 0; i < uniforms.size(); i++) {
+ if (uniforms[i].name == p_name) {
+ return uniforms[i].type;
+ }
+ }
+ return UniformType::UNIFORM_TYPE_FLOAT;
+}
+
+VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < uniforms.size()) {
+ return uniforms[p_idx].type;
+ }
+ return UniformType::UNIFORM_TYPE_FLOAT;
+}
+
+String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ switch (uniform_type) {
+ case UniformType::UNIFORM_TYPE_FLOAT:
+ if (uniform_name == "[None]") {
+ return "\t" + p_output_vars[0] + " = 0.0;\n";
+ }
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+ case UniformType::UNIFORM_TYPE_INT:
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+ case UniformType::UNIFORM_TYPE_BOOLEAN:
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+ case UniformType::UNIFORM_TYPE_VECTOR:
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+ case UniformType::UNIFORM_TYPE_TRANSFORM:
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+ case UniformType::UNIFORM_TYPE_COLOR: {
+ String code = "\t" + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n";
+ code += "\t" + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n";
+ return code;
+ } break;
+ case UniformType::UNIFORM_TYPE_SAMPLER:
+ break;
+ default:
+ break;
+ }
+ return "";
+}
+
+void VisualShaderNodeUniformRef::_set_uniform_type(int p_uniform_type) {
+ uniform_type = (UniformType)p_uniform_type;
+}
+
+int VisualShaderNodeUniformRef::_get_uniform_type() const {
+ return (int)uniform_type;
+}
+
+void VisualShaderNodeUniformRef::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniformRef::set_uniform_name);
+ ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniformRef::get_uniform_name);
+
+ ClassDB::bind_method(D_METHOD("_set_uniform_type", "type"), &VisualShaderNodeUniformRef::_set_uniform_type);
+ ClassDB::bind_method(D_METHOD("_get_uniform_type"), &VisualShaderNodeUniformRef::_get_uniform_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name", PROPERTY_HINT_ENUM, ""), "set_uniform_name", "get_uniform_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "uniform_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_uniform_type", "_get_uniform_type");
+}
+
+Vector<StringName> VisualShaderNodeUniformRef::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("uniform_name");
+ props.push_back("uniform_type");
+ return props;
+}
+
+VisualShaderNodeUniformRef::VisualShaderNodeUniformRef() {
}
////////////////////////////////////////////
@@ -1912,18 +2387,38 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
// Canvas Item, Light
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" },
- // Particles, Vertex
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
- { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, NULL, NULL },
+ // Particles, Emit
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
+ // Particles, Process
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
+ // Particles, End
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
+ // Sky, Fragment
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR" },
+ { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "ALPHA" },
+
+ { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, nullptr, nullptr },
};
int VisualShaderNodeOutput::get_input_port_count() const {
-
int idx = 0;
int count = 0;
@@ -1938,7 +2433,6 @@ int VisualShaderNodeOutput::get_input_port_count() const {
}
VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_input_port_type(int p_port) const {
-
int idx = 0;
int count = 0;
@@ -1956,7 +2450,6 @@ VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_input_port_type(int
}
String VisualShaderNodeOutput::get_input_port_name(int p_port) const {
-
int idx = 0;
int count = 0;
@@ -1978,18 +2471,18 @@ Variant VisualShaderNodeOutput::get_input_port_default_value(int p_port) const {
}
int VisualShaderNodeOutput::get_output_port_count() const {
-
return 0;
}
+
VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeOutput::get_output_port_name(int p_port) const {
return String();
}
bool VisualShaderNodeOutput::is_port_separator(int p_index) const {
-
if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_FRAGMENT) {
String name = get_input_port_name(p_index);
return (name == "Normal" || name == "Rim" || name == "Alpha Scissor");
@@ -2002,14 +2495,12 @@ String VisualShaderNodeOutput::get_caption() const {
}
String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
int idx = 0;
int count = 0;
String code;
while (ports[idx].mode != Shader::MODE_MAX) {
if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
-
if (p_input_vars[count] != String()) {
String s = ports[idx].string;
if (s.find(":") != -1) {
@@ -2041,12 +2532,69 @@ String VisualShaderNodeUniform::get_uniform_name() const {
return uniform_name;
}
-void VisualShaderNodeUniform::_bind_methods() {
+void VisualShaderNodeUniform::set_qualifier(VisualShaderNodeUniform::Qualifier p_qual) {
+ qualifier = p_qual;
+ emit_changed();
+}
+VisualShaderNodeUniform::Qualifier VisualShaderNodeUniform::get_qualifier() const {
+ return qualifier;
+}
+
+void VisualShaderNodeUniform::set_global_code_generated(bool p_enabled) {
+ global_code_generated = p_enabled;
+}
+
+bool VisualShaderNodeUniform::is_global_code_generated() const {
+ return global_code_generated;
+}
+
+void VisualShaderNodeUniform::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name);
ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "uniform_name"), "set_uniform_name", "get_uniform_name");
+ ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeUniform::set_qualifier);
+ ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeUniform::get_qualifier);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "qualifier", PROPERTY_HINT_ENUM, "None,Global,Instance"), "set_qualifier", "get_qualifier");
+
+ BIND_ENUM_CONSTANT(QUAL_NONE);
+ BIND_ENUM_CONSTANT(QUAL_GLOBAL);
+ BIND_ENUM_CONSTANT(QUAL_INSTANCE);
+}
+
+String VisualShaderNodeUniform::_get_qual_str() const {
+ if (is_qualifier_supported(qualifier)) {
+ switch (qualifier) {
+ case QUAL_NONE:
+ break;
+ case QUAL_GLOBAL:
+ return "global ";
+ case QUAL_INSTANCE:
+ return "instance ";
+ }
+ }
+ return String();
+}
+
+String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ List<String> keyword_list;
+ ShaderLanguage::get_keyword_list(&keyword_list);
+ if (keyword_list.find(uniform_name)) {
+ return TTR("Uniform name cannot be equal to a shader keyword. Choose another name.");
+ }
+ if (!is_qualifier_supported(qualifier)) {
+ return "This uniform type does not support that qualifier.";
+ }
+
+ return String();
+}
+
+Vector<StringName> VisualShaderNodeUniform::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("qualifier");
+ return props;
}
VisualShaderNodeUniform::VisualShaderNodeUniform() {
@@ -2067,9 +2615,9 @@ Vector2 VisualShaderNodeGroupBase::get_size() const {
}
void VisualShaderNodeGroupBase::set_inputs(const String &p_inputs) {
-
- if (inputs == p_inputs)
+ if (inputs == p_inputs) {
return;
+ }
clear_input_ports();
@@ -2080,7 +2628,6 @@ void VisualShaderNodeGroupBase::set_inputs(const String &p_inputs) {
int input_port_count = input_strings.size();
for (int i = 0; i < input_port_count; i++) {
-
Vector<String> arr = input_strings[i].split(",");
ERR_FAIL_COND(arr.size() != 3);
@@ -2100,9 +2647,9 @@ String VisualShaderNodeGroupBase::get_inputs() const {
}
void VisualShaderNodeGroupBase::set_outputs(const String &p_outputs) {
-
- if (outputs == p_outputs)
+ if (outputs == p_outputs) {
return;
+ }
clear_output_ports();
@@ -2113,7 +2660,6 @@ void VisualShaderNodeGroupBase::set_outputs(const String &p_outputs) {
int output_port_count = output_strings.size();
for (int i = 0; i < output_port_count; i++) {
-
Vector<String> arr = output_strings[i].split(",");
ERR_FAIL_COND(arr.size() != 3);
@@ -2150,7 +2696,6 @@ bool VisualShaderNodeGroupBase::is_valid_port_name(const String &p_name) const {
}
void VisualShaderNodeGroupBase::add_input_port(int p_id, int p_type, const String &p_name) {
-
String str = itos(p_id) + "," + itos(p_type) + "," + p_name + ";";
Vector<String> inputs_strings = inputs.split(";", false);
int index = 0;
@@ -2184,10 +2729,10 @@ void VisualShaderNodeGroupBase::add_input_port(int p_id, int p_type, const Strin
}
_apply_port_changes();
+ emit_changed();
}
void VisualShaderNodeGroupBase::remove_input_port(int p_id) {
-
ERR_FAIL_COND(!has_input_port(p_id));
Vector<String> inputs_strings = inputs.split(";", false);
@@ -2209,6 +2754,7 @@ void VisualShaderNodeGroupBase::remove_input_port(int p_id) {
}
_apply_port_changes();
+ emit_changed();
}
int VisualShaderNodeGroupBase::get_input_port_count() const {
@@ -2220,7 +2766,6 @@ bool VisualShaderNodeGroupBase::has_input_port(int p_id) const {
}
void VisualShaderNodeGroupBase::add_output_port(int p_id, int p_type, const String &p_name) {
-
String str = itos(p_id) + "," + itos(p_type) + "," + p_name + ";";
Vector<String> outputs_strings = outputs.split(";", false);
int index = 0;
@@ -2254,10 +2799,10 @@ void VisualShaderNodeGroupBase::add_output_port(int p_id, int p_type, const Stri
}
_apply_port_changes();
+ emit_changed();
}
void VisualShaderNodeGroupBase::remove_output_port(int p_id) {
-
ERR_FAIL_COND(!has_output_port(p_id));
Vector<String> outputs_strings = outputs.split(";", false);
@@ -2279,6 +2824,7 @@ void VisualShaderNodeGroupBase::remove_output_port(int p_id) {
}
_apply_port_changes();
+ emit_changed();
}
int VisualShaderNodeGroupBase::get_output_port_count() const {
@@ -2298,12 +2844,12 @@ void VisualShaderNodeGroupBase::clear_output_ports() {
}
void VisualShaderNodeGroupBase::set_input_port_type(int p_id, int p_type) {
-
ERR_FAIL_COND(!has_input_port(p_id));
ERR_FAIL_COND(p_type < 0 || p_type >= PORT_TYPE_MAX);
- if (input_ports[p_id].type == p_type)
+ if (input_ports[p_id].type == p_type) {
return;
+ }
Vector<String> inputs_strings = inputs.split(";", false);
int count = 0;
@@ -2325,6 +2871,7 @@ void VisualShaderNodeGroupBase::set_input_port_type(int p_id, int p_type) {
inputs = inputs.insert(index, itos(p_type));
_apply_port_changes();
+ emit_changed();
}
VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_input_port_type(int p_id) const {
@@ -2333,12 +2880,12 @@ VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_input_port_ty
}
void VisualShaderNodeGroupBase::set_input_port_name(int p_id, const String &p_name) {
-
ERR_FAIL_COND(!has_input_port(p_id));
ERR_FAIL_COND(!is_valid_port_name(p_name));
- if (input_ports[p_id].name == p_name)
+ if (input_ports[p_id].name == p_name) {
return;
+ }
Vector<String> inputs_strings = inputs.split(";", false);
int count = 0;
@@ -2360,6 +2907,7 @@ void VisualShaderNodeGroupBase::set_input_port_name(int p_id, const String &p_na
inputs = inputs.insert(index, p_name);
_apply_port_changes();
+ emit_changed();
}
String VisualShaderNodeGroupBase::get_input_port_name(int p_id) const {
@@ -2368,12 +2916,12 @@ String VisualShaderNodeGroupBase::get_input_port_name(int p_id) const {
}
void VisualShaderNodeGroupBase::set_output_port_type(int p_id, int p_type) {
-
ERR_FAIL_COND(!has_output_port(p_id));
ERR_FAIL_COND(p_type < 0 || p_type >= PORT_TYPE_MAX);
- if (output_ports[p_id].type == p_type)
+ if (output_ports[p_id].type == p_type) {
return;
+ }
Vector<String> output_strings = outputs.split(";", false);
int count = 0;
@@ -2395,6 +2943,7 @@ void VisualShaderNodeGroupBase::set_output_port_type(int p_id, int p_type) {
outputs = outputs.insert(index, itos(p_type));
_apply_port_changes();
+ emit_changed();
}
VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_output_port_type(int p_id) const {
@@ -2403,12 +2952,12 @@ VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_output_port_t
}
void VisualShaderNodeGroupBase::set_output_port_name(int p_id, const String &p_name) {
-
ERR_FAIL_COND(!has_output_port(p_id));
ERR_FAIL_COND(!is_valid_port_name(p_name));
- if (output_ports[p_id].name == p_name)
+ if (output_ports[p_id].name == p_name) {
return;
+ }
Vector<String> output_strings = outputs.split(";", false);
int count = 0;
@@ -2430,6 +2979,7 @@ void VisualShaderNodeGroupBase::set_output_port_name(int p_id, const String &p_n
outputs = outputs.insert(index, p_name);
_apply_port_changes();
+ emit_changed();
}
String VisualShaderNodeGroupBase::get_output_port_name(int p_id) const {
@@ -2450,12 +3000,11 @@ void VisualShaderNodeGroupBase::set_control(Control *p_control, int p_index) {
}
Control *VisualShaderNodeGroupBase::get_control(int p_index) {
- ERR_FAIL_COND_V(!controls.has(p_index), NULL);
+ ERR_FAIL_COND_V(!controls.has(p_index), nullptr);
return controls[p_index];
}
void VisualShaderNodeGroupBase::_apply_port_changes() {
-
Vector<String> inputs_strings = inputs.split(";", false);
Vector<String> outputs_strings = outputs.split(";", false);
@@ -2491,7 +3040,6 @@ bool VisualShaderNodeGroupBase::is_editable() const {
}
void VisualShaderNodeGroupBase::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualShaderNodeGroupBase::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &VisualShaderNodeGroupBase::get_size);
@@ -2531,10 +3079,6 @@ String VisualShaderNodeGroupBase::generate_code(Shader::Mode p_mode, VisualShade
}
VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() {
- size = Size2(0, 0);
- inputs = "";
- outputs = "";
- editable = false;
simple_decl = false;
}
@@ -2546,6 +3090,7 @@ String VisualShaderNodeExpression::get_caption() const {
void VisualShaderNodeExpression::set_expression(const String &p_expression) {
expression = p_expression;
+ emit_changed();
}
String VisualShaderNodeExpression::get_expression() const {
@@ -2553,7 +3098,6 @@ String VisualShaderNodeExpression::get_expression() const {
}
String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String _expression = expression;
_expression = _expression.insert(0, "\n");
@@ -2625,6 +3169,9 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
case PORT_TYPE_SCALAR:
tk = "0.0";
break;
+ case PORT_TYPE_SCALAR_INT:
+ tk = "0";
+ break;
case PORT_TYPE_VECTOR:
tk = "vec3(0.0, 0.0, 0.0)";
break;
@@ -2650,7 +3197,6 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
}
void VisualShaderNodeExpression::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_expression", "expression"), &VisualShaderNodeExpression::set_expression);
ClassDB::bind_method(D_METHOD("get_expression"), &VisualShaderNodeExpression::get_expression);
@@ -2658,7 +3204,6 @@ void VisualShaderNodeExpression::_bind_methods() {
}
VisualShaderNodeExpression::VisualShaderNodeExpression() {
- expression = "";
set_editable(true);
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index f35318e090..e7d74b6c17 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -41,11 +41,18 @@ class VisualShaderNode;
class VisualShader : public Shader {
GDCLASS(VisualShader, Shader);
+ friend class VisualShaderNodeVersionChecker;
+
+ String version = "";
+
public:
enum Type {
TYPE_VERTEX,
TYPE_FRAGMENT,
TYPE_LIGHT,
+ TYPE_EMIT,
+ TYPE_PROCESS,
+ TYPE_END,
TYPE_MAX
};
@@ -58,10 +65,12 @@ public:
struct DefaultTextureParam {
StringName name;
- Ref<Texture> param;
+ Ref<Texture2D> param;
};
private:
+ Type current_type;
+
struct Node {
Ref<VisualShaderNode> node;
Vector2 position;
@@ -73,7 +82,7 @@ private:
List<Connection> connections;
} graph[TYPE_MAX];
- Shader::Mode shader_mode;
+ Shader::Mode shader_mode = Shader::MODE_SPATIAL;
mutable String previous_code;
Array _get_node_connections(Type p_type) const;
@@ -90,11 +99,10 @@ private:
static RenderModeEnums render_mode_enums[];
- volatile mutable bool dirty;
+ volatile mutable bool dirty = true;
void _queue_update();
union ConnectionKey {
-
struct {
uint64_t node : 32;
uint64_t port : 32;
@@ -108,16 +116,26 @@ private:
Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const;
void _input_type_changed(Type p_type, int p_id);
+ bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const;
protected:
- virtual void _update_shader() const;
+ virtual void _update_shader() const override;
static void _bind_methods();
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+public: // internal methods
+ void set_shader_type(Type p_type);
+ Type get_shader_type() const;
+
public:
+ void set_version(const String &p_version);
+ String get_version() const;
+
+ void update_version(const String &p_new_version);
+
enum {
NODE_ID_INVALID = -1,
NODE_ID_OUTPUT = 0,
@@ -148,9 +166,9 @@ public:
void get_node_connections(Type p_type, List<Connection> *r_connections) const;
void set_mode(Mode p_mode);
- virtual Mode get_mode() const;
+ virtual Mode get_mode() const override;
- virtual bool is_text_shader() const;
+ virtual bool is_text_shader() const override;
void set_graph_offset(const Vector2 &p_offset);
Vector2 get_graph_offset() const;
@@ -171,17 +189,21 @@ VARIANT_ENUM_CAST(VisualShader::Type)
class VisualShaderNode : public Resource {
GDCLASS(VisualShaderNode, Resource);
- int port_preview;
+ int port_preview = -1;
Map<int, Variant> default_input_values;
+ Map<int, bool> connected_input_ports;
+ Map<int, bool> connected_output_ports;
+ int connected_output_count = 0;
protected:
- bool simple_decl;
+ bool simple_decl = true;
static void _bind_methods();
public:
enum PortType {
PORT_TYPE_SCALAR,
+ PORT_TYPE_SCALAR_INT,
PORT_TYPE_VECTOR,
PORT_TYPE_BOOLEAN,
PORT_TYPE_TRANSFORM,
@@ -213,6 +235,16 @@ public:
virtual bool is_port_separator(int p_index) const;
+ bool is_output_port_connected(int p_port) const;
+ void set_output_port_connected(int p_port, bool p_connected);
+ bool is_input_port_connected(int p_port) const;
+ void set_input_port_connected(int p_port, bool p_connected);
+ virtual bool is_generate_input_var(int p_port) const;
+
+ virtual bool is_code_generated() const;
+ virtual bool is_show_prop_names() const;
+ virtual bool is_use_prop_slots() const;
+
virtual Vector<StringName> get_editable_properties() const;
virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
@@ -242,19 +274,19 @@ class VisualShaderNodeCustom : public VisualShaderNode {
friend class VisualShaderEditor;
protected:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
protected:
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
- virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
static void _bind_methods();
@@ -269,8 +301,8 @@ class VisualShaderNodeInput : public VisualShaderNode {
GDCLASS(VisualShaderNodeInput, VisualShaderNode);
friend class VisualShader;
- VisualShader::Type shader_type;
- Shader::Mode shader_mode;
+ VisualShader::Type shader_type = VisualShader::TYPE_MAX;
+ Shader::Mode shader_mode = Shader::MODE_MAX;
struct Port {
Shader::Mode mode;
@@ -283,24 +315,24 @@ class VisualShaderNodeInput : public VisualShaderNode {
static const Port ports[];
static const Port preview_ports[];
- String input_name;
+ String input_name = "[None]";
protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
void set_input_name(String p_name);
String get_input_name() const;
@@ -312,7 +344,7 @@ public:
PortType get_input_type_by_name(String p_name) const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeInput();
};
@@ -338,20 +370,20 @@ public:
static const Port ports[];
public:
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
Variant get_input_port_default_value(int p_port) const;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual bool is_port_separator(int p_index) const;
+ virtual bool is_port_separator(int p_index) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeOutput();
};
@@ -359,19 +391,102 @@ public:
class VisualShaderNodeUniform : public VisualShaderNode {
GDCLASS(VisualShaderNodeUniform, VisualShaderNode);
+public:
+ enum Qualifier {
+ QUAL_NONE,
+ QUAL_GLOBAL,
+ QUAL_INSTANCE,
+ };
+
private:
- String uniform_name;
+ String uniform_name = "";
+ Qualifier qualifier = QUAL_NONE;
+ bool global_code_generated = false;
protected:
static void _bind_methods();
+ String _get_qual_str() const;
public:
void set_uniform_name(const String &p_name);
String get_uniform_name() const;
+ void set_qualifier(Qualifier p_qual);
+ Qualifier get_qualifier() const;
+
+ void set_global_code_generated(bool p_enabled);
+ bool is_global_code_generated() const;
+
+ virtual bool is_qualifier_supported(Qualifier p_qual) const = 0;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
+
VisualShaderNodeUniform();
};
+VARIANT_ENUM_CAST(VisualShaderNodeUniform::Qualifier)
+
+class VisualShaderNodeUniformRef : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeUniformRef, VisualShaderNode);
+
+public:
+ enum UniformType {
+ UNIFORM_TYPE_FLOAT,
+ UNIFORM_TYPE_INT,
+ UNIFORM_TYPE_BOOLEAN,
+ UNIFORM_TYPE_VECTOR,
+ UNIFORM_TYPE_TRANSFORM,
+ UNIFORM_TYPE_COLOR,
+ UNIFORM_TYPE_SAMPLER,
+ };
+
+ struct Uniform {
+ String name;
+ UniformType type;
+ };
+
+private:
+ String uniform_name = "[None]";
+ UniformType uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
+
+protected:
+ static void _bind_methods();
+
+public:
+ static void add_uniform(const String &p_name, UniformType p_type);
+ static void clear_uniforms();
+ static bool has_uniform(const String &p_name);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ void set_uniform_name(const String &p_name);
+ String get_uniform_name() const;
+
+ void _set_uniform_type(int p_uniform_type);
+ int _get_uniform_type() const;
+
+ int get_uniforms_count() const;
+ String get_uniform_name_by_index(int p_idx) const;
+ UniformType get_uniform_type_by_name(const String &p_name) const;
+ UniformType get_uniform_type_by_index(int p_idx) const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ VisualShaderNodeUniformRef();
+};
+
class VisualShaderNodeGroupBase : public VisualShaderNode {
GDCLASS(VisualShaderNodeGroupBase, VisualShaderNode);
@@ -379,10 +494,10 @@ private:
void _apply_port_changes();
protected:
- Vector2 size;
- String inputs;
- String outputs;
- bool editable;
+ Vector2 size = Size2(0, 0);
+ String inputs = "";
+ String outputs = "";
+ bool editable = false;
struct Port {
PortType type;
@@ -397,7 +512,7 @@ protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
void set_size(const Vector2 &p_size);
Vector2 get_size() const;
@@ -412,25 +527,25 @@ public:
void add_input_port(int p_id, int p_type, const String &p_name);
void remove_input_port(int p_id);
- virtual int get_input_port_count() const;
+ virtual int get_input_port_count() const override;
bool has_input_port(int p_id) const;
void clear_input_ports();
void add_output_port(int p_id, int p_type, const String &p_name);
void remove_output_port(int p_id);
- virtual int get_output_port_count() const;
+ virtual int get_output_port_count() const override;
bool has_output_port(int p_id) const;
void clear_output_ports();
void set_input_port_type(int p_id, int p_type);
- virtual PortType get_input_port_type(int p_id) const;
+ virtual PortType get_input_port_type(int p_id) const override;
void set_input_port_name(int p_id, const String &p_name);
- virtual String get_input_port_name(int p_id) const;
+ virtual String get_input_port_name(int p_id) const override;
void set_output_port_type(int p_id, int p_type);
- virtual PortType get_output_port_type(int p_id) const;
+ virtual PortType get_output_port_type(int p_id) const override;
void set_output_port_name(int p_id, const String &p_name);
- virtual String get_output_port_name(int p_id) const;
+ virtual String get_output_port_name(int p_id) const override;
int get_free_input_port_id() const;
int get_free_output_port_id() const;
@@ -441,7 +556,7 @@ public:
void set_editable(bool p_enabled);
bool is_editable() const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeGroupBase();
};
@@ -450,17 +565,17 @@ class VisualShaderNodeExpression : public VisualShaderNodeGroupBase {
GDCLASS(VisualShaderNodeExpression, VisualShaderNodeGroupBase);
protected:
- String expression;
+ String expression = "";
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
void set_expression(const String &p_expression);
String get_expression() const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeExpression();
};
@@ -469,9 +584,9 @@ class VisualShaderNodeGlobalExpression : public VisualShaderNodeExpression {
GDCLASS(VisualShaderNodeGlobalExpression, VisualShaderNodeExpression);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
VisualShaderNodeGlobalExpression();
};
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index daf770e92a..cffe0bb5cd 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -30,67 +30,122 @@
#include "visual_shader_nodes.h"
-////////////// Scalar
+////////////// Scalar(Float)
-String VisualShaderNodeScalarConstant::get_caption() const {
- return "Scalar";
+String VisualShaderNodeFloatConstant::get_caption() const {
+ return "ScalarFloat";
}
-int VisualShaderNodeScalarConstant::get_input_port_count() const {
+int VisualShaderNodeFloatConstant::get_input_port_count() const {
return 0;
}
-VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_input_port_type(int p_port) const {
+VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const {
+String VisualShaderNodeFloatConstant::get_input_port_name(int p_port) const {
return String();
}
-int VisualShaderNodeScalarConstant::get_output_port_count() const {
+int VisualShaderNodeFloatConstant::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_output_port_type(int p_port) const {
+VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const {
+String VisualShaderNodeFloatConstant::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
-String VisualShaderNodeScalarConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeFloatConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + vformat("%.6f", constant) + ";\n";
}
-void VisualShaderNodeScalarConstant::set_constant(float p_value) {
-
+void VisualShaderNodeFloatConstant::set_constant(float p_value) {
constant = p_value;
emit_changed();
}
-float VisualShaderNodeScalarConstant::get_constant() const {
-
+float VisualShaderNodeFloatConstant::get_constant() const {
return constant;
}
-Vector<StringName> VisualShaderNodeScalarConstant::get_editable_properties() const {
+Vector<StringName> VisualShaderNodeFloatConstant::get_editable_properties() const {
Vector<StringName> props;
props.push_back("constant");
return props;
}
-void VisualShaderNodeScalarConstant::_bind_methods() {
+void VisualShaderNodeFloatConstant::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeFloatConstant::set_constant);
+ ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeFloatConstant::get_constant);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant"), "set_constant", "get_constant");
+}
+
+VisualShaderNodeFloatConstant::VisualShaderNodeFloatConstant() {
+}
+
+////////////// Scalar(Int)
+
+String VisualShaderNodeIntConstant::get_caption() const {
+ return "ScalarInt";
+}
+
+int VisualShaderNodeIntConstant::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
+
+String VisualShaderNodeIntConstant::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeIntConstant::get_output_port_count() const {
+ return 1;
+}
- ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeScalarConstant::set_constant);
- ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeScalarConstant::get_constant);
+VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant"), "set_constant", "get_constant");
+String VisualShaderNodeIntConstant::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
}
-VisualShaderNodeScalarConstant::VisualShaderNodeScalarConstant() {
- constant = 0;
+String VisualShaderNodeIntConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = " + itos(constant) + ";\n";
+}
+
+void VisualShaderNodeIntConstant::set_constant(int p_value) {
+ constant = p_value;
+ emit_changed();
+}
+
+int VisualShaderNodeIntConstant::get_constant() const {
+ return constant;
+}
+
+Vector<StringName> VisualShaderNodeIntConstant::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("constant");
+ return props;
+}
+
+void VisualShaderNodeIntConstant::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeIntConstant::set_constant);
+ ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeIntConstant::get_constant);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "constant"), "set_constant", "get_constant");
+}
+
+VisualShaderNodeIntConstant::VisualShaderNodeIntConstant() {
}
////////////// Boolean
@@ -143,7 +198,6 @@ Vector<StringName> VisualShaderNodeBooleanConstant::get_editable_properties() co
}
void VisualShaderNodeBooleanConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeBooleanConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeBooleanConstant::get_constant);
@@ -151,7 +205,6 @@ void VisualShaderNodeBooleanConstant::_bind_methods() {
}
VisualShaderNodeBooleanConstant::VisualShaderNodeBooleanConstant() {
- constant = false;
}
////////////// Color
@@ -185,7 +238,6 @@ String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const {
}
String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
code += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f, %.6f, %.6f)", constant.r, constant.g, constant.b) + ";\n";
code += "\t" + p_output_vars[1] + " = " + vformat("%.6f", constant.a) + ";\n";
@@ -194,13 +246,11 @@ String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualS
}
void VisualShaderNodeColorConstant::set_constant(Color p_value) {
-
constant = p_value;
emit_changed();
}
Color VisualShaderNodeColorConstant::get_constant() const {
-
return constant;
}
@@ -211,7 +261,6 @@ Vector<StringName> VisualShaderNodeColorConstant::get_editable_properties() cons
}
void VisualShaderNodeColorConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeColorConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeColorConstant::get_constant);
@@ -219,7 +268,6 @@ void VisualShaderNodeColorConstant::_bind_methods() {
}
VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() {
- constant = Color(1, 1, 1, 1);
}
////////////// Vector
@@ -257,13 +305,11 @@ String VisualShaderNodeVec3Constant::generate_code(Shader::Mode p_mode, VisualSh
}
void VisualShaderNodeVec3Constant::set_constant(Vector3 p_value) {
-
constant = p_value;
emit_changed();
}
Vector3 VisualShaderNodeVec3Constant::get_constant() const {
-
return constant;
}
@@ -274,7 +320,6 @@ Vector<StringName> VisualShaderNodeVec3Constant::get_editable_properties() const
}
void VisualShaderNodeVec3Constant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeVec3Constant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec3Constant::get_constant);
@@ -327,13 +372,11 @@ String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, Vis
}
void VisualShaderNodeTransformConstant::set_constant(Transform p_value) {
-
constant = p_value;
emit_changed();
}
Transform VisualShaderNodeTransformConstant::get_constant() const {
-
return constant;
}
@@ -344,7 +387,6 @@ Vector<StringName> VisualShaderNodeTransformConstant::get_editable_properties()
}
void VisualShaderNodeTransformConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeTransformConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeTransformConstant::get_constant);
@@ -357,7 +399,7 @@ VisualShaderNodeTransformConstant::VisualShaderNodeTransformConstant() {
////////////// Texture
String VisualShaderNodeTexture::get_caption() const {
- return "Texture";
+ return "Texture2D";
}
int VisualShaderNodeTexture::get_input_port_count() const {
@@ -365,7 +407,6 @@ int VisualShaderNodeTexture::get_input_port_count() const {
}
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const {
-
switch (p_port) {
case 0:
return PORT_TYPE_VECTOR;
@@ -379,7 +420,6 @@ VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(i
}
String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
-
switch (p_port) {
case 0:
return "uv";
@@ -397,14 +437,16 @@ int VisualShaderNodeTexture::get_output_port_count() const {
}
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type(int p_port) const {
- if (p_port == 0 && source == SOURCE_DEPTH)
+ if (p_port == 0 && source == SOURCE_DEPTH) {
return PORT_TYPE_SCALAR;
+ }
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
String VisualShaderNodeTexture::get_output_port_name(int p_port) const {
- if (p_port == 0 && source == SOURCE_DEPTH)
+ if (p_port == 0 && source == SOURCE_DEPTH) {
return "depth";
+ }
return p_port == 0 ? "rgb" : "alpha";
}
@@ -416,7 +458,6 @@ String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const {
}
static String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name) {
-
static const char *typepf[VisualShader::TYPE_MAX] = { "vtx", "frg", "lgt" };
return p_name + "_" + String(typepf[p_type]) + "_" + itos(p_id);
}
@@ -431,14 +472,17 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture::get_default_t
}
String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
if (source == SOURCE_TEXTURE) {
-
String u = "uniform sampler2D " + make_unique_id(p_type, p_id, "tex");
switch (texture_type) {
- case TYPE_DATA: break;
- case TYPE_COLOR: u += " : hint_albedo"; break;
- case TYPE_NORMALMAP: u += " : hint_normal"; break;
+ case TYPE_DATA:
+ break;
+ case TYPE_COLOR:
+ u += " : hint_albedo";
+ break;
+ case TYPE_NORMALMAP:
+ u += " : hint_normal";
+ break;
}
return u + ";\n";
}
@@ -447,7 +491,6 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade
}
String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
if (source == SOURCE_TEXTURE) {
String id = make_unique_id(p_type, p_id, "tex");
String code;
@@ -502,7 +545,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default.
@@ -526,7 +568,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -550,7 +591,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -584,7 +624,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -649,14 +688,12 @@ VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const {
return source;
}
-void VisualShaderNodeTexture::set_texture(Ref<Texture> p_value) {
-
+void VisualShaderNodeTexture::set_texture(Ref<Texture2D> p_value) {
texture = p_value;
emit_changed();
}
-Ref<Texture> VisualShaderNodeTexture::get_texture() const {
-
+Ref<Texture2D> VisualShaderNodeTexture::get_texture() const {
return texture;
}
@@ -680,7 +717,6 @@ Vector<StringName> VisualShaderNodeTexture::get_editable_properties() const {
}
String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
-
if (source == SOURCE_TEXTURE) {
return String(); // all good
}
@@ -690,22 +726,18 @@ String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::T
}
if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
-
return String(); // all good
}
if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
-
return String(); // all good
}
if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM) {
-
return String(); // all good
}
if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
-
if (get_output_port_for_preview() == 0) { // DEPTH_TEXTURE is not supported in preview(canvas_item) shader
return TTR("Invalid source for preview.");
}
@@ -716,7 +748,6 @@ String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::T
}
void VisualShaderNodeTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeTexture::set_source);
ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeTexture::get_source);
@@ -727,7 +758,7 @@ void VisualShaderNodeTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type");
BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
@@ -742,21 +773,253 @@ void VisualShaderNodeTexture::_bind_methods() {
}
VisualShaderNodeTexture::VisualShaderNodeTexture() {
- texture_type = TYPE_DATA;
- source = SOURCE_TEXTURE;
}
-////////////// CubeMap
+////////////// Sample3D
+
+int VisualShaderNodeSample3D::get_input_port_count() const {
+ return 3;
+}
+
+VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_input_port_type(int p_port) const {
+ switch (p_port) {
+ case 0:
+ return PORT_TYPE_VECTOR;
+ case 1:
+ return PORT_TYPE_SCALAR;
+ case 2:
+ return PORT_TYPE_SAMPLER;
+ default:
+ return PORT_TYPE_SCALAR;
+ }
+}
+
+String VisualShaderNodeSample3D::get_input_port_name(int p_port) const {
+ switch (p_port) {
+ case 0:
+ return "uvw";
+ case 1:
+ return "lod";
+ default:
+ return "";
+ }
+}
+
+int VisualShaderNodeSample3D::get_output_port_count() const {
+ return 2;
+}
+
+VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_output_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeSample3D::get_output_port_name(int p_port) const {
+ return p_port == 0 ? "rgb" : "alpha";
+}
+
+String VisualShaderNodeSample3D::get_input_port_default_hint(int p_port) const {
+ if (p_port == 0) {
+ return "vec3(UV.xy, 0.0)";
+ }
+ return "";
+}
+
+String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ String code;
+ if (source == SOURCE_TEXTURE || source == SOURCE_PORT) {
+ String id;
+ code += "\t{\n";
+ if (source == SOURCE_TEXTURE) {
+ id = make_unique_id(p_type, p_id, "tex3d");
+ } else {
+ id = p_input_vars[2];
+ }
+ if (id != String()) {
+ if (p_input_vars[0] == String()) { // Use UV by default.
+ if (p_input_vars[1] == String()) {
+ code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", vec3(UV.xy, 0.0));\n";
+ } else {
+ code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", vec3(UV.xy, 0.0), " + p_input_vars[1] + ");\n";
+ }
+ } else if (p_input_vars[1] == String()) {
+ //no lod
+ code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n";
+ } else {
+ code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ }
+ } else {
+ code += "\t\tvec4 " + id + "_tex_read = vec4(0.0);\n";
+ }
+
+ code += "\t\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = " + id + "_tex_read.a;\n";
+ code += "\t}\n";
+ return code;
+ }
+ code += "\t" + p_output_vars[0] + " = vec3(0.0);\n";
+ code += "\t" + p_output_vars[1] + " = 1.0;\n";
+ return code;
+}
+
+void VisualShaderNodeSample3D::set_source(Source p_source) {
+ source = p_source;
+ emit_changed();
+ emit_signal("editor_refresh_request");
+}
+
+VisualShaderNodeSample3D::Source VisualShaderNodeSample3D::get_source() const {
+ return source;
+}
+
+void VisualShaderNodeSample3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeSample3D::set_source);
+ ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeSample3D::get_source);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source");
+
+ BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
+ BIND_ENUM_CONSTANT(SOURCE_PORT);
+}
+
+String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ if (source == SOURCE_TEXTURE) {
+ return String(); // all good
+ }
+ if (source == SOURCE_PORT) {
+ return String(); // all good
+ }
+ return TTR("Invalid source for shader.");
+}
+
+VisualShaderNodeSample3D::VisualShaderNodeSample3D() {
+ simple_decl = false;
+}
+
+////////////// Texture2DArray
+
+String VisualShaderNodeTexture2DArray::get_caption() const {
+ return "Texture2DArray";
+}
+
+String VisualShaderNodeTexture2DArray::get_input_port_name(int p_port) const {
+ if (p_port == 2) {
+ return "sampler2DArray";
+ }
+ return VisualShaderNodeSample3D::get_input_port_name(p_port);
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture2DArray::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "tex3d");
+ dtp.param = texture;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+String VisualShaderNodeTexture2DArray::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ if (source == SOURCE_TEXTURE) {
+ return "uniform sampler2DArray " + make_unique_id(p_type, p_id, "tex3d") + ";\n";
+ }
+ return String();
+}
+
+void VisualShaderNodeTexture2DArray::set_texture_array(Ref<Texture2DArray> p_value) {
+ texture = p_value;
+ emit_changed();
+}
+
+Ref<Texture2DArray> VisualShaderNodeTexture2DArray::get_texture_array() const {
+ return texture;
+}
+
+Vector<StringName> VisualShaderNodeTexture2DArray::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("source");
+ if (source == SOURCE_TEXTURE) {
+ props.push_back("texture_array");
+ }
+ return props;
+}
+
+void VisualShaderNodeTexture2DArray::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture_array", "value"), &VisualShaderNodeTexture2DArray::set_texture_array);
+ ClassDB::bind_method(D_METHOD("get_texture_array"), &VisualShaderNodeTexture2DArray::get_texture_array);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_array", PROPERTY_HINT_RESOURCE_TYPE, "Texture2DArray"), "set_texture_array", "get_texture_array");
+}
+
+VisualShaderNodeTexture2DArray::VisualShaderNodeTexture2DArray() {
+}
+
+////////////// Texture3D
+
+String VisualShaderNodeTexture3D::get_caption() const {
+ return "Texture3D";
+}
+
+String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const {
+ if (p_port == 2) {
+ return "sampler3D";
+ }
+ return VisualShaderNodeSample3D::get_input_port_name(p_port);
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "tex3d");
+ dtp.param = texture;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+String VisualShaderNodeTexture3D::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ if (source == SOURCE_TEXTURE) {
+ return "uniform sampler3D " + make_unique_id(p_type, p_id, "tex3d") + ";\n";
+ }
+ return String();
+}
+
+void VisualShaderNodeTexture3D::set_texture(Ref<Texture3D> p_value) {
+ texture = p_value;
+ emit_changed();
+}
+
+Ref<Texture3D> VisualShaderNodeTexture3D::get_texture() const {
+ return texture;
+}
+
+Vector<StringName> VisualShaderNodeTexture3D::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("source");
+ if (source == SOURCE_TEXTURE) {
+ props.push_back("texture");
+ }
+ return props;
+}
+
+void VisualShaderNodeTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture3D::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture3D::get_texture);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
+}
+
+VisualShaderNodeTexture3D::VisualShaderNodeTexture3D() {
+}
+
+////////////// Cubemap
-String VisualShaderNodeCubeMap::get_caption() const {
- return "CubeMap";
+String VisualShaderNodeCubemap::get_caption() const {
+ return "Cubemap";
}
-int VisualShaderNodeCubeMap::get_input_port_count() const {
+int VisualShaderNodeCubemap::get_input_port_count() const {
return 3;
}
-VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const {
+VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_input_port_type(int p_port) const {
switch (p_port) {
case 0:
return PORT_TYPE_VECTOR;
@@ -769,7 +1032,7 @@ VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(i
}
}
-String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
+String VisualShaderNodeCubemap::get_input_port_name(int p_port) const {
switch (p_port) {
case 0:
return "uv";
@@ -782,19 +1045,19 @@ String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
}
}
-int VisualShaderNodeCubeMap::get_output_port_count() const {
+int VisualShaderNodeCubemap::get_output_port_count() const {
return 2;
}
-VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_output_port_type(int p_port) const {
+VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
-String VisualShaderNodeCubeMap::get_output_port_name(int p_port) const {
+String VisualShaderNodeCubemap::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
-Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
VisualShader::DefaultTextureParam dtp;
dtp.name = make_unique_id(p_type, p_id, "cube");
dtp.param = cube_map;
@@ -803,22 +1066,25 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_t
return ret;
}
-String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
+String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
if (source == SOURCE_TEXTURE) {
String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube");
switch (texture_type) {
- case TYPE_DATA: break;
- case TYPE_COLOR: u += " : hint_albedo"; break;
- case TYPE_NORMALMAP: u += " : hint_normal"; break;
+ case TYPE_DATA:
+ break;
+ case TYPE_COLOR:
+ u += " : hint_albedo";
+ break;
+ case TYPE_NORMALMAP:
+ u += " : hint_normal";
+ break;
}
return u + ";\n";
}
return String();
}
-String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
+String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
String id;
if (source == SOURCE_TEXTURE) {
@@ -860,44 +1126,42 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader:
return code;
}
-String VisualShaderNodeCubeMap::get_input_port_default_hint(int p_port) const {
+String VisualShaderNodeCubemap::get_input_port_default_hint(int p_port) const {
if (p_port == 0) {
return "vec3(UV, 0.0)";
}
return "";
}
-void VisualShaderNodeCubeMap::set_source(Source p_source) {
+void VisualShaderNodeCubemap::set_source(Source p_source) {
source = p_source;
emit_changed();
emit_signal("editor_refresh_request");
}
-VisualShaderNodeCubeMap::Source VisualShaderNodeCubeMap::get_source() const {
+VisualShaderNodeCubemap::Source VisualShaderNodeCubemap::get_source() const {
return source;
}
-void VisualShaderNodeCubeMap::set_cube_map(Ref<CubeMap> p_value) {
-
+void VisualShaderNodeCubemap::set_cube_map(Ref<Cubemap> p_value) {
cube_map = p_value;
emit_changed();
}
-Ref<CubeMap> VisualShaderNodeCubeMap::get_cube_map() const {
-
+Ref<Cubemap> VisualShaderNodeCubemap::get_cube_map() const {
return cube_map;
}
-void VisualShaderNodeCubeMap::set_texture_type(TextureType p_type) {
+void VisualShaderNodeCubemap::set_texture_type(TextureType p_type) {
texture_type = p_type;
emit_changed();
}
-VisualShaderNodeCubeMap::TextureType VisualShaderNodeCubeMap::get_texture_type() const {
+VisualShaderNodeCubemap::TextureType VisualShaderNodeCubemap::get_texture_type() const {
return texture_type;
}
-Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const {
+Vector<StringName> VisualShaderNodeCubemap::get_editable_properties() const {
Vector<StringName> props;
props.push_back("source");
if (source == SOURCE_TEXTURE) {
@@ -907,19 +1171,18 @@ Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const {
return props;
}
-void VisualShaderNodeCubeMap::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubeMap::set_source);
- ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubeMap::get_source);
+void VisualShaderNodeCubemap::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubemap::set_source);
+ ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubemap::get_source);
- ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubeMap::set_cube_map);
- ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubeMap::get_cube_map);
+ ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubemap::set_cube_map);
+ ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubemap::get_cube_map);
- ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubeMap::set_texture_type);
- ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubeMap::get_texture_type);
+ ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubemap::set_texture_type);
+ ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubemap::get_texture_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "CubeMap"), "set_cube_map", "get_cube_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "Cubemap"), "set_cube_map", "get_cube_map");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type");
BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
@@ -930,83 +1193,96 @@ void VisualShaderNodeCubeMap::_bind_methods() {
BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
}
-VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() {
- texture_type = TYPE_DATA;
- source = SOURCE_TEXTURE;
+VisualShaderNodeCubemap::VisualShaderNodeCubemap() {
simple_decl = false;
}
-////////////// Scalar Op
+////////////// Float Op
-String VisualShaderNodeScalarOp::get_caption() const {
- return "ScalarOp";
+String VisualShaderNodeFloatOp::get_caption() const {
+ return "FloatOp";
}
-int VisualShaderNodeScalarOp::get_input_port_count() const {
+int VisualShaderNodeFloatOp::get_input_port_count() const {
return 2;
}
-VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_input_port_type(int p_port) const {
+VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const {
+String VisualShaderNodeFloatOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
-int VisualShaderNodeScalarOp::get_output_port_count() const {
+int VisualShaderNodeFloatOp::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_output_port_type(int p_port) const {
+VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const {
+String VisualShaderNodeFloatOp::get_output_port_name(int p_port) const {
return "op"; //no output port means the editor will be used as port
}
-String VisualShaderNodeScalarOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
+String VisualShaderNodeFloatOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code = "\t" + p_output_vars[0] + " = ";
switch (op) {
-
- case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break;
- case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break;
- case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break;
- case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break;
- case OP_MOD: code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_POW: code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_ATAN2: code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
+ case OP_ADD:
+ code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
+ break;
+ case OP_SUB:
+ code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MUL:
+ code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
+ break;
+ case OP_DIV:
+ code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MOD:
+ code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_POW:
+ code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MAX:
+ code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MIN:
+ code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_ATAN2:
+ code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_STEP:
+ code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
}
return code;
}
-void VisualShaderNodeScalarOp::set_operator(Operator p_op) {
-
+void VisualShaderNodeFloatOp::set_operator(Operator p_op) {
op = p_op;
emit_changed();
}
-VisualShaderNodeScalarOp::Operator VisualShaderNodeScalarOp::get_operator() const {
-
+VisualShaderNodeFloatOp::Operator VisualShaderNodeFloatOp::get_operator() const {
return op;
}
-Vector<StringName> VisualShaderNodeScalarOp::get_editable_properties() const {
+Vector<StringName> VisualShaderNodeFloatOp::get_editable_properties() const {
Vector<StringName> props;
props.push_back("operator");
return props;
}
-void VisualShaderNodeScalarOp::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeScalarOp::set_operator);
- ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeScalarOp::get_operator);
+void VisualShaderNodeFloatOp::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator);
+ ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator);
ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Atan2,Step"), "set_operator", "get_operator");
@@ -1022,12 +1298,105 @@ void VisualShaderNodeScalarOp::_bind_methods() {
BIND_ENUM_CONSTANT(OP_STEP);
}
-VisualShaderNodeScalarOp::VisualShaderNodeScalarOp() {
- op = OP_ADD;
+VisualShaderNodeFloatOp::VisualShaderNodeFloatOp() {
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
}
+////////////// Integer Op
+
+String VisualShaderNodeIntOp::get_caption() const {
+ return "IntOp";
+}
+
+int VisualShaderNodeIntOp::get_input_port_count() const {
+ return 2;
+}
+
+VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
+
+String VisualShaderNodeIntOp::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "a" : "b";
+}
+
+int VisualShaderNodeIntOp::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
+
+String VisualShaderNodeIntOp::get_output_port_name(int p_port) const {
+ return "op"; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeIntOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ String code = "\t" + p_output_vars[0] + " = ";
+ switch (op) {
+ case OP_ADD:
+ code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
+ break;
+ case OP_SUB:
+ code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MUL:
+ code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
+ break;
+ case OP_DIV:
+ code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MOD:
+ code += p_input_vars[0] + " % " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MAX:
+ code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MIN:
+ code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ }
+
+ return code;
+}
+
+void VisualShaderNodeIntOp::set_operator(Operator p_op) {
+ op = p_op;
+ emit_changed();
+}
+
+VisualShaderNodeIntOp::Operator VisualShaderNodeIntOp::get_operator() const {
+ return op;
+}
+
+Vector<StringName> VisualShaderNodeIntOp::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("operator");
+ return props;
+}
+
+void VisualShaderNodeIntOp::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator);
+ ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator");
+
+ BIND_ENUM_CONSTANT(OP_ADD);
+ BIND_ENUM_CONSTANT(OP_SUB);
+ BIND_ENUM_CONSTANT(OP_MUL);
+ BIND_ENUM_CONSTANT(OP_DIV);
+ BIND_ENUM_CONSTANT(OP_MOD);
+ BIND_ENUM_CONSTANT(OP_MAX);
+ BIND_ENUM_CONSTANT(OP_MIN);
+}
+
+VisualShaderNodeIntOp::VisualShaderNodeIntOp() {
+ set_input_port_default_value(0, 0);
+ set_input_port_default_value(1, 0);
+}
+
////////////// Vector Op
String VisualShaderNodeVectorOp::get_caption() const {
@@ -1059,35 +1428,55 @@ String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const {
}
String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code = "\t" + p_output_vars[0] + " = ";
switch (op) {
-
- case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break;
- case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break;
- case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break;
- case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break;
- case OP_MOD: code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_POW: code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_CROSS: code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_ATAN2: code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_REFLECT: code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
+ case OP_ADD:
+ code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
+ break;
+ case OP_SUB:
+ code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MUL:
+ code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
+ break;
+ case OP_DIV:
+ code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MOD:
+ code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_POW:
+ code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MAX:
+ code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MIN:
+ code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_CROSS:
+ code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_ATAN2:
+ code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_REFLECT:
+ code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_STEP:
+ code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
}
return code;
}
void VisualShaderNodeVectorOp::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
VisualShaderNodeVectorOp::Operator VisualShaderNodeVectorOp::get_operator() const {
-
return op;
}
@@ -1098,7 +1487,6 @@ Vector<StringName> VisualShaderNodeVectorOp::get_editable_properties() const {
}
void VisualShaderNodeVectorOp::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator);
@@ -1119,7 +1507,6 @@ void VisualShaderNodeVectorOp::_bind_methods() {
}
VisualShaderNodeVectorOp::VisualShaderNodeVectorOp() {
- op = OP_ADD;
set_input_port_default_value(0, Vector3());
set_input_port_default_value(1, Vector3());
}
@@ -1155,29 +1542,23 @@ String VisualShaderNodeColorOp::get_output_port_name(int p_port) const {
}
String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
static const char *axisn[3] = { "x", "y", "z" };
switch (op) {
case OP_SCREEN: {
-
code += "\t" + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") * (vec3(1.0) - " + p_input_vars[1] + ");\n";
} break;
case OP_DIFFERENCE: {
-
code += "\t" + p_output_vars[0] + " = abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ");\n";
} break;
case OP_DARKEN: {
-
code += "\t" + p_output_vars[0] + " = min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
} break;
case OP_LIGHTEN: {
-
code += "\t" + p_output_vars[0] + " = max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
} break;
case OP_OVERLAY: {
-
for (int i = 0; i < 3; i++) {
code += "\t{\n";
code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
@@ -1192,16 +1573,13 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader:
} break;
case OP_DODGE: {
-
code += "\t" + p_output_vars[0] + " = (" + p_input_vars[0] + ") / (vec3(1.0) - " + p_input_vars[1] + ");\n";
} break;
case OP_BURN: {
-
code += "\t" + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") / (" + p_input_vars[1] + ");\n";
} break;
case OP_SOFT_LIGHT: {
-
for (int i = 0; i < 3; i++) {
code += "\t{\n";
code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
@@ -1216,7 +1594,6 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader:
} break;
case OP_HARD_LIGHT: {
-
for (int i = 0; i < 3; i++) {
code += "\t{\n";
code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
@@ -1236,7 +1613,6 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader:
}
void VisualShaderNodeColorOp::set_operator(Operator p_op) {
-
op = p_op;
switch (op) {
case OP_SCREEN:
@@ -1271,7 +1647,6 @@ void VisualShaderNodeColorOp::set_operator(Operator p_op) {
}
VisualShaderNodeColorOp::Operator VisualShaderNodeColorOp::get_operator() const {
-
return op;
}
@@ -1282,7 +1657,6 @@ Vector<StringName> VisualShaderNodeColorOp::get_editable_properties() const {
}
void VisualShaderNodeColorOp::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeColorOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeColorOp::get_operator);
@@ -1300,7 +1674,6 @@ void VisualShaderNodeColorOp::_bind_methods() {
}
VisualShaderNodeColorOp::VisualShaderNodeColorOp() {
- op = OP_SCREEN;
set_input_port_default_value(0, Vector3());
set_input_port_default_value(1, Vector3());
}
@@ -1336,7 +1709,6 @@ String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const {
}
String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
if (op == OP_AxB) {
return "\t" + p_output_vars[0] + " = " + p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
} else if (op == OP_BxA) {
@@ -1349,13 +1721,11 @@ String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualS
}
void VisualShaderNodeTransformMult::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
VisualShaderNodeTransformMult::Operator VisualShaderNodeTransformMult::get_operator() const {
-
return op;
}
@@ -1366,7 +1736,6 @@ Vector<StringName> VisualShaderNodeTransformMult::get_editable_properties() cons
}
void VisualShaderNodeTransformMult::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformMult::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformMult::get_operator);
@@ -1379,7 +1748,6 @@ void VisualShaderNodeTransformMult::_bind_methods() {
}
VisualShaderNodeTransformMult::VisualShaderNodeTransformMult() {
- op = OP_AxB;
set_input_port_default_value(0, Transform());
set_input_port_default_value(1, Transform());
}
@@ -1427,13 +1795,11 @@ String VisualShaderNodeTransformVecMult::generate_code(Shader::Mode p_mode, Visu
}
void VisualShaderNodeTransformVecMult::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
VisualShaderNodeTransformVecMult::Operator VisualShaderNodeTransformVecMult::get_operator() const {
-
return op;
}
@@ -1444,7 +1810,6 @@ Vector<StringName> VisualShaderNodeTransformVecMult::get_editable_properties() c
}
void VisualShaderNodeTransformVecMult::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformVecMult::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformVecMult::get_operator);
@@ -1457,43 +1822,41 @@ void VisualShaderNodeTransformVecMult::_bind_methods() {
}
VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() {
- op = OP_AxB;
set_input_port_default_value(0, Transform());
set_input_port_default_value(1, Vector3());
}
-////////////// Scalar Func
+////////////// Float Func
-String VisualShaderNodeScalarFunc::get_caption() const {
- return "ScalarFunc";
+String VisualShaderNodeFloatFunc::get_caption() const {
+ return "FloatFunc";
}
-int VisualShaderNodeScalarFunc::get_input_port_count() const {
+int VisualShaderNodeFloatFunc::get_input_port_count() const {
return 1;
}
-VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_input_port_type(int p_port) const {
+VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const {
+String VisualShaderNodeFloatFunc::get_input_port_name(int p_port) const {
return "";
}
-int VisualShaderNodeScalarFunc::get_output_port_count() const {
+int VisualShaderNodeFloatFunc::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_output_port_type(int p_port) const {
+VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const {
+String VisualShaderNodeFloatFunc::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
-String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
+String VisualShaderNodeFloatFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
static const char *scalar_func_id[FUNC_ONEMINUS + 1] = {
"sin($)",
"cos($)",
@@ -1532,27 +1895,24 @@ String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShad
return "\t" + p_output_vars[0] + " = " + String(scalar_func_id[func]).replace("$", p_input_vars[0]) + ";\n";
}
-void VisualShaderNodeScalarFunc::set_function(Function p_func) {
-
+void VisualShaderNodeFloatFunc::set_function(Function p_func) {
func = p_func;
emit_changed();
}
-VisualShaderNodeScalarFunc::Function VisualShaderNodeScalarFunc::get_function() const {
-
+VisualShaderNodeFloatFunc::Function VisualShaderNodeFloatFunc::get_function() const {
return func;
}
-Vector<StringName> VisualShaderNodeScalarFunc::get_editable_properties() const {
+Vector<StringName> VisualShaderNodeFloatFunc::get_editable_properties() const {
Vector<StringName> props;
props.push_back("function");
return props;
}
-void VisualShaderNodeScalarFunc::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarFunc::set_function);
- ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarFunc::get_function);
+void VisualShaderNodeFloatFunc::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeFloatFunc::set_function);
+ ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeFloatFunc::get_function);
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sin,Cos,Tan,ASin,ACos,ATan,SinH,CosH,TanH,Log,Exp,Sqrt,Abs,Sign,Floor,Round,Ceil,Frac,Saturate,Negate,ACosH,ASinH,ATanH,Degrees,Exp2,InverseSqrt,Log2,Radians,Reciprocal,RoundEven,Trunc,OneMinus"), "set_function", "get_function");
@@ -1590,11 +1950,104 @@ void VisualShaderNodeScalarFunc::_bind_methods() {
BIND_ENUM_CONSTANT(FUNC_ONEMINUS);
}
-VisualShaderNodeScalarFunc::VisualShaderNodeScalarFunc() {
- func = FUNC_SIGN;
+VisualShaderNodeFloatFunc::VisualShaderNodeFloatFunc() {
set_input_port_default_value(0, 0.0);
}
+////////////// Int Func
+
+String VisualShaderNodeIntFunc::get_caption() const {
+ return "IntFunc";
+}
+
+int VisualShaderNodeIntFunc::get_input_port_count() const {
+ if (func == FUNC_CLAMP) {
+ return 3;
+ }
+ return 1;
+}
+
+VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
+
+String VisualShaderNodeIntFunc::get_input_port_name(int p_port) const {
+ if (func == FUNC_CLAMP) {
+ if (p_port == 0) {
+ return "";
+ } else if (p_port == 1) {
+ return "min";
+ } else if (p_port == 2) {
+ return "max";
+ }
+ }
+ return "";
+}
+
+int VisualShaderNodeIntFunc::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
+
+String VisualShaderNodeIntFunc::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ if (func == FUNC_CLAMP) {
+ return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+ }
+
+ static const char *int_func_id[FUNC_SIGN + 1] = {
+ "abs($)",
+ "",
+ "-($)",
+ "sign($)"
+ };
+
+ return "\t" + p_output_vars[0] + " = " + String(int_func_id[func]).replace("$", p_input_vars[0]) + ";\n";
+}
+
+void VisualShaderNodeIntFunc::set_function(Function p_func) {
+ if (func != p_func) {
+ if (p_func == FUNC_CLAMP) {
+ set_input_port_default_value(1, 0);
+ set_input_port_default_value(2, 0);
+ }
+ }
+ func = p_func;
+ emit_changed();
+}
+
+VisualShaderNodeIntFunc::Function VisualShaderNodeIntFunc::get_function() const {
+ return func;
+}
+
+Vector<StringName> VisualShaderNodeIntFunc::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("function");
+ return props;
+}
+
+void VisualShaderNodeIntFunc::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function);
+ ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Clamp,Negate,Sign"), "set_function", "get_function");
+
+ BIND_ENUM_CONSTANT(FUNC_ABS);
+ BIND_ENUM_CONSTANT(FUNC_CLAMP);
+ BIND_ENUM_CONSTANT(FUNC_NEGATE);
+ BIND_ENUM_CONSTANT(FUNC_SIGN);
+}
+
+VisualShaderNodeIntFunc::VisualShaderNodeIntFunc() {
+ set_input_port_default_value(0, 0);
+}
+
////////////// Vector Func
String VisualShaderNodeVectorFunc::get_caption() const {
@@ -1626,7 +2079,6 @@ String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *vec_func_id[FUNC_ONEMINUS + 1] = {
"normalize($)",
"max(min($, vec3(1.0)), vec3(0.0))",
@@ -1693,7 +2145,6 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad
}
void VisualShaderNodeVectorFunc::set_function(Function p_func) {
-
func = p_func;
if (func == FUNC_RGB2HSV) {
simple_decl = false;
@@ -1706,7 +2157,6 @@ void VisualShaderNodeVectorFunc::set_function(Function p_func) {
}
VisualShaderNodeVectorFunc::Function VisualShaderNodeVectorFunc::get_function() const {
-
return func;
}
@@ -1717,7 +2167,6 @@ Vector<StringName> VisualShaderNodeVectorFunc::get_editable_properties() const {
}
void VisualShaderNodeVectorFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorFunc::get_function);
@@ -1761,7 +2210,6 @@ void VisualShaderNodeVectorFunc::_bind_methods() {
}
VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() {
- func = FUNC_NORMALIZE;
set_input_port_default_value(0, Vector3());
}
@@ -1796,7 +2244,6 @@ String VisualShaderNodeColorFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeColorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
switch (func) {
@@ -1824,13 +2271,11 @@ String VisualShaderNodeColorFunc::generate_code(Shader::Mode p_mode, VisualShade
}
void VisualShaderNodeColorFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeColorFunc::Function VisualShaderNodeColorFunc::get_function() const {
-
return func;
}
@@ -1841,7 +2286,6 @@ Vector<StringName> VisualShaderNodeColorFunc::get_editable_properties() const {
}
void VisualShaderNodeColorFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeColorFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeColorFunc::get_function);
@@ -1852,9 +2296,8 @@ void VisualShaderNodeColorFunc::_bind_methods() {
}
VisualShaderNodeColorFunc::VisualShaderNodeColorFunc() {
- func = FUNC_GRAYSCALE;
- set_input_port_default_value(0, Vector3());
simple_decl = false;
+ set_input_port_default_value(0, Vector3());
}
////////////// Transform Func
@@ -1888,7 +2331,6 @@ String VisualShaderNodeTransformFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeTransformFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_TRANSPOSE + 1] = {
"inverse($)",
"transpose($)"
@@ -1900,13 +2342,11 @@ String VisualShaderNodeTransformFunc::generate_code(Shader::Mode p_mode, VisualS
}
void VisualShaderNodeTransformFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeTransformFunc::Function VisualShaderNodeTransformFunc::get_function() const {
-
return func;
}
@@ -1917,7 +2357,6 @@ Vector<StringName> VisualShaderNodeTransformFunc::get_editable_properties() cons
}
void VisualShaderNodeTransformFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeTransformFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeTransformFunc::get_function);
@@ -1928,7 +2367,6 @@ void VisualShaderNodeTransformFunc::_bind_methods() {
}
VisualShaderNodeTransformFunc::VisualShaderNodeTransformFunc() {
- func = FUNC_INVERSE;
set_input_port_default_value(0, Transform());
}
@@ -2078,7 +2516,6 @@ String VisualShaderNodeScalarDerivativeFunc::get_output_port_name(int p_port) co
}
String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_Y + 1] = {
"fwidth($)",
"dFdx($)",
@@ -2091,13 +2528,11 @@ String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode,
}
void VisualShaderNodeScalarDerivativeFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeScalarDerivativeFunc::Function VisualShaderNodeScalarDerivativeFunc::get_function() const {
-
return func;
}
@@ -2108,7 +2543,6 @@ Vector<StringName> VisualShaderNodeScalarDerivativeFunc::get_editable_properties
}
void VisualShaderNodeScalarDerivativeFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarDerivativeFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarDerivativeFunc::get_function);
@@ -2120,7 +2554,6 @@ void VisualShaderNodeScalarDerivativeFunc::_bind_methods() {
}
VisualShaderNodeScalarDerivativeFunc::VisualShaderNodeScalarDerivativeFunc() {
- func = FUNC_SUM;
set_input_port_default_value(0, 0.0);
}
@@ -2155,7 +2588,6 @@ String VisualShaderNodeVectorDerivativeFunc::get_output_port_name(int p_port) co
}
String VisualShaderNodeVectorDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_Y + 1] = {
"fwidth($)",
"dFdx($)",
@@ -2168,13 +2600,11 @@ String VisualShaderNodeVectorDerivativeFunc::generate_code(Shader::Mode p_mode,
}
void VisualShaderNodeVectorDerivativeFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeVectorDerivativeFunc::Function VisualShaderNodeVectorDerivativeFunc::get_function() const {
-
return func;
}
@@ -2185,7 +2615,6 @@ Vector<StringName> VisualShaderNodeVectorDerivativeFunc::get_editable_properties
}
void VisualShaderNodeVectorDerivativeFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorDerivativeFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorDerivativeFunc::get_function);
@@ -2197,7 +2626,6 @@ void VisualShaderNodeVectorDerivativeFunc::_bind_methods() {
}
VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() {
- func = FUNC_SUM;
set_input_port_default_value(0, Vector3());
}
@@ -2216,12 +2644,13 @@ VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_input_por
}
String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "min";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "max";
+ }
return "";
}
@@ -2262,12 +2691,13 @@ VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_input_por
}
String VisualShaderNodeVectorClamp::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "min";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "max";
+ }
return "";
}
@@ -2406,10 +2836,11 @@ VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get
}
String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "x";
+ }
return "";
}
@@ -2449,12 +2880,13 @@ VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get
}
String VisualShaderNodeScalarSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge0";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "edge1";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "x";
+ }
return "";
}
@@ -2495,12 +2927,13 @@ VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get
}
String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge0";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "edge1";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "x";
+ }
return "";
}
@@ -2546,12 +2979,13 @@ VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmo
}
String VisualShaderNodeVectorScalarSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge0";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "edge1";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "x";
+ }
return "";
}
@@ -2632,7 +3066,6 @@ int VisualShaderNodeVectorRefract::get_input_port_count() const {
}
VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_input_port_type(int p_port) const {
-
if (p_port == 2) {
return PORT_TYPE_SCALAR;
}
@@ -2776,8 +3209,9 @@ int VisualShaderNodeVectorScalarMix::get_input_port_count() const {
}
VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_input_port_type(int p_port) const {
- if (p_port == 2)
+ if (p_port == 2) {
return PORT_TYPE_SCALAR;
+ }
return PORT_TYPE_VECTOR;
}
@@ -2854,7 +3288,6 @@ String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualS
}
VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() {
-
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, 0.0);
@@ -2903,7 +3336,6 @@ String VisualShaderNodeTransformCompose::generate_code(Shader::Mode p_mode, Visu
}
VisualShaderNodeTransformCompose::VisualShaderNodeTransformCompose() {
-
set_input_port_default_value(0, Vector3());
set_input_port_default_value(1, Vector3());
set_input_port_default_value(2, Vector3());
@@ -3008,45 +3440,338 @@ VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() {
set_input_port_default_value(0, Transform());
}
-////////////// Scalar Uniform
+////////////// Float Uniform
-String VisualShaderNodeScalarUniform::get_caption() const {
- return "ScalarUniform";
+String VisualShaderNodeFloatUniform::get_caption() const {
+ return "FloatUniform";
}
-int VisualShaderNodeScalarUniform::get_input_port_count() const {
+int VisualShaderNodeFloatUniform::get_input_port_count() const {
return 0;
}
-VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_input_port_type(int p_port) const {
+VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const {
+String VisualShaderNodeFloatUniform::get_input_port_name(int p_port) const {
return String();
}
-int VisualShaderNodeScalarUniform::get_output_port_count() const {
+int VisualShaderNodeFloatUniform::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_output_port_type(int p_port) const {
+VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const {
+String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = "";
+ if (hint == HINT_RANGE) {
+ code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")";
+ } else if (hint == HINT_RANGE_STEP) {
+ code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")";
+ } else {
+ code += _get_qual_str() + "uniform float " + get_uniform_name();
+ }
+ if (default_value_enabled) {
+ code += " = " + rtos(default_value);
+ }
+ code += ";\n";
+ return code;
+}
+
+String VisualShaderNodeFloatUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+}
+
+bool VisualShaderNodeFloatUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeFloatUniform::is_use_prop_slots() const {
+ return true;
+}
+
+void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) {
+ hint = p_hint;
+ emit_changed();
+}
+
+VisualShaderNodeFloatUniform::Hint VisualShaderNodeFloatUniform::get_hint() const {
+ return hint;
+}
+
+void VisualShaderNodeFloatUniform::set_min(float p_value) {
+ hint_range_min = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeFloatUniform::get_min() const {
+ return hint_range_min;
+}
+
+void VisualShaderNodeFloatUniform::set_max(float p_value) {
+ hint_range_max = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeFloatUniform::get_max() const {
+ return hint_range_max;
+}
+
+void VisualShaderNodeFloatUniform::set_step(float p_value) {
+ hint_range_step = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeFloatUniform::get_step() const {
+ return hint_range_step;
+}
+
+void VisualShaderNodeFloatUniform::set_default_value_enabled(bool p_enabled) {
+ default_value_enabled = p_enabled;
+ emit_changed();
+}
+
+bool VisualShaderNodeFloatUniform::is_default_value_enabled() const {
+ return default_value_enabled;
+}
+
+void VisualShaderNodeFloatUniform::set_default_value(float p_value) {
+ default_value = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeFloatUniform::get_default_value() const {
+ return default_value;
+}
+
+void VisualShaderNodeFloatUniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatUniform::set_hint);
+ ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatUniform::get_hint);
+
+ ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatUniform::set_min);
+ ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatUniform::get_min);
+
+ ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatUniform::set_max);
+ ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatUniform::get_max);
+
+ ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatUniform::set_step);
+ ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatUniform::get_step);
+
+ ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeFloatUniform::set_default_value_enabled);
+ ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeFloatUniform::is_default_value_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeFloatUniform::set_default_value);
+ ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeFloatUniform::get_default_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min"), "set_min", "get_min");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max"), "set_max", "get_max");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step"), "set_step", "get_step");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_value"), "set_default_value", "get_default_value");
+
+ BIND_ENUM_CONSTANT(HINT_NONE);
+ BIND_ENUM_CONSTANT(HINT_RANGE);
+ BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
+}
+
+bool VisualShaderNodeFloatUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
+Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const {
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
+ props.push_back("hint");
+ if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
+ props.push_back("min");
+ props.push_back("max");
+ }
+ if (hint == HINT_RANGE_STEP) {
+ props.push_back("step");
+ }
+ props.push_back("default_value_enabled");
+ if (default_value_enabled) {
+ props.push_back("default_value");
+ }
+ return props;
+}
+
+VisualShaderNodeFloatUniform::VisualShaderNodeFloatUniform() {
+}
+
+////////////// Integer Uniform
+
+String VisualShaderNodeIntUniform::get_caption() const {
+ return "IntUniform";
+}
+
+int VisualShaderNodeIntUniform::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
+
+String VisualShaderNodeIntUniform::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeIntUniform::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR_INT;
+}
+
+String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
-String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- return "uniform float " + get_uniform_name() + ";\n";
+String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = "";
+ if (hint == HINT_RANGE) {
+ code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")";
+ } else if (hint == HINT_RANGE_STEP) {
+ code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ", " + itos(hint_range_step) + ")";
+ } else {
+ code += _get_qual_str() + "uniform int " + get_uniform_name();
+ }
+ if (default_value_enabled) {
+ code += " = " + itos(default_value);
+ }
+ code += ";\n";
+ return code;
}
-String VisualShaderNodeScalarUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeIntUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
-VisualShaderNodeScalarUniform::VisualShaderNodeScalarUniform() {
+bool VisualShaderNodeIntUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeIntUniform::is_use_prop_slots() const {
+ return true;
+}
+
+void VisualShaderNodeIntUniform::set_hint(Hint p_hint) {
+ hint = p_hint;
+ emit_changed();
+}
+
+VisualShaderNodeIntUniform::Hint VisualShaderNodeIntUniform::get_hint() const {
+ return hint;
+}
+
+void VisualShaderNodeIntUniform::set_min(int p_value) {
+ hint_range_min = p_value;
+ emit_changed();
+}
+
+int VisualShaderNodeIntUniform::get_min() const {
+ return hint_range_min;
+}
+
+void VisualShaderNodeIntUniform::set_max(int p_value) {
+ hint_range_max = p_value;
+ emit_changed();
+}
+
+int VisualShaderNodeIntUniform::get_max() const {
+ return hint_range_max;
+}
+
+void VisualShaderNodeIntUniform::set_step(int p_value) {
+ hint_range_step = p_value;
+ emit_changed();
+}
+
+int VisualShaderNodeIntUniform::get_step() const {
+ return hint_range_step;
+}
+
+void VisualShaderNodeIntUniform::set_default_value_enabled(bool p_enabled) {
+ default_value_enabled = p_enabled;
+ emit_changed();
+}
+
+bool VisualShaderNodeIntUniform::is_default_value_enabled() const {
+ return default_value_enabled;
+}
+
+void VisualShaderNodeIntUniform::set_default_value(int p_value) {
+ default_value = p_value;
+ emit_changed();
+}
+
+int VisualShaderNodeIntUniform::get_default_value() const {
+ return default_value;
+}
+
+void VisualShaderNodeIntUniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntUniform::set_hint);
+ ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntUniform::get_hint);
+
+ ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntUniform::set_min);
+ ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntUniform::get_min);
+
+ ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntUniform::set_max);
+ ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntUniform::get_max);
+
+ ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntUniform::set_step);
+ ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntUniform::get_step);
+
+ ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeIntUniform::set_default_value_enabled);
+ ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeIntUniform::is_default_value_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntUniform::set_default_value);
+ ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntUniform::get_default_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "default_value"), "set_default_value", "get_default_value");
+
+ BIND_ENUM_CONSTANT(HINT_NONE);
+ BIND_ENUM_CONSTANT(HINT_RANGE);
+ BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
+}
+
+bool VisualShaderNodeIntUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
+Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const {
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
+ props.push_back("hint");
+ if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
+ props.push_back("min");
+ props.push_back("max");
+ }
+ if (hint == HINT_RANGE_STEP) {
+ props.push_back("step");
+ }
+ props.push_back("default_value_enabled");
+ if (default_value_enabled) {
+ props.push_back("default_value");
+ }
+ return props;
+}
+
+VisualShaderNodeIntUniform::VisualShaderNodeIntUniform() {
}
////////////// Boolean Uniform
@@ -3079,14 +3804,73 @@ String VisualShaderNodeBooleanUniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
+void VisualShaderNodeBooleanUniform::set_default_value_enabled(bool p_enabled) {
+ default_value_enabled = p_enabled;
+ emit_changed();
+}
+
+bool VisualShaderNodeBooleanUniform::is_default_value_enabled() const {
+ return default_value_enabled;
+}
+
+void VisualShaderNodeBooleanUniform::set_default_value(bool p_value) {
+ default_value = p_value;
+ emit_changed();
+}
+
+bool VisualShaderNodeBooleanUniform::get_default_value() const {
+ return default_value;
+}
+
String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- return "uniform bool " + get_uniform_name() + ";\n";
+ String code = _get_qual_str() + "uniform bool " + get_uniform_name();
+ if (default_value_enabled) {
+ if (default_value) {
+ code += " = true";
+ } else {
+ code += " = false";
+ }
+ }
+ code += ";\n";
+ return code;
}
String VisualShaderNodeBooleanUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+bool VisualShaderNodeBooleanUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeBooleanUniform::is_use_prop_slots() const {
+ return true;
+}
+
+void VisualShaderNodeBooleanUniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanUniform::set_default_value_enabled);
+ ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanUniform::is_default_value_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanUniform::set_default_value);
+ ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanUniform::get_default_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value"), "set_default_value", "get_default_value");
+}
+
+bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
+Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() const {
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
+ props.push_back("default_value_enabled");
+ if (default_value_enabled) {
+ props.push_back("default_value");
+ }
+ return props;
+}
+
VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() {
}
@@ -3120,9 +3904,31 @@ String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const {
return p_port == 0 ? "color" : "alpha"; //no output port means the editor will be used as port
}
-String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+void VisualShaderNodeColorUniform::set_default_value_enabled(bool p_enabled) {
+ default_value_enabled = p_enabled;
+ emit_changed();
+}
+
+bool VisualShaderNodeColorUniform::is_default_value_enabled() const {
+ return default_value_enabled;
+}
- return "uniform vec4 " + get_uniform_name() + " : hint_color;\n";
+void VisualShaderNodeColorUniform::set_default_value(const Color &p_value) {
+ default_value = p_value;
+ emit_changed();
+}
+
+Color VisualShaderNodeColorUniform::get_default_value() const {
+ return default_value;
+}
+
+String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = _get_qual_str() + "uniform vec4 " + get_uniform_name() + " : hint_color";
+ if (default_value_enabled) {
+ code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.r, default_value.g, default_value.b, default_value.a);
+ }
+ code += ";\n";
+ return code;
}
String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -3131,6 +3937,34 @@ String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualSh
return code;
}
+bool VisualShaderNodeColorUniform::is_show_prop_names() const {
+ return true;
+}
+
+void VisualShaderNodeColorUniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorUniform::set_default_value_enabled);
+ ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorUniform::is_default_value_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorUniform::set_default_value);
+ ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorUniform::get_default_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_value"), "set_default_value", "get_default_value");
+}
+
+bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
+Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const {
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
+ props.push_back("default_value_enabled");
+ if (default_value_enabled) {
+ props.push_back("default_value");
+ }
+ return props;
+}
+
VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
}
@@ -3164,14 +3998,69 @@ String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
+void VisualShaderNodeVec3Uniform::set_default_value_enabled(bool p_enabled) {
+ default_value_enabled = p_enabled;
+ emit_changed();
+}
+
+bool VisualShaderNodeVec3Uniform::is_default_value_enabled() const {
+ return default_value_enabled;
+}
+
+void VisualShaderNodeVec3Uniform::set_default_value(const Vector3 &p_value) {
+ default_value = p_value;
+ emit_changed();
+}
+
+Vector3 VisualShaderNodeVec3Uniform::get_default_value() const {
+ return default_value;
+}
+
String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- return "uniform vec3 " + get_uniform_name() + ";\n";
+ String code = _get_qual_str() + "uniform vec3 " + get_uniform_name();
+ if (default_value_enabled) {
+ code += vformat(" = vec3(%.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z);
+ }
+ code += ";\n";
+ return code;
}
String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+void VisualShaderNodeVec3Uniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Uniform::set_default_value_enabled);
+ ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Uniform::is_default_value_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Uniform::set_default_value);
+ ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Uniform::get_default_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_value"), "set_default_value", "get_default_value");
+}
+
+bool VisualShaderNodeVec3Uniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeVec3Uniform::is_use_prop_slots() const {
+ return true;
+}
+
+bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
+Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const {
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
+ props.push_back("default_value_enabled");
+ if (default_value_enabled) {
+ props.push_back("default_value");
+ }
+ return props;
+}
+
VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() {
}
@@ -3205,14 +4094,73 @@ String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const
return ""; //no output port means the editor will be used as port
}
+void VisualShaderNodeTransformUniform::set_default_value_enabled(bool p_enabled) {
+ default_value_enabled = p_enabled;
+ emit_changed();
+}
+
+bool VisualShaderNodeTransformUniform::is_default_value_enabled() const {
+ return default_value_enabled;
+}
+
+void VisualShaderNodeTransformUniform::set_default_value(const Transform &p_value) {
+ default_value = p_value;
+ emit_changed();
+}
+
+Transform VisualShaderNodeTransformUniform::get_default_value() const {
+ return default_value;
+}
+
String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- return "uniform mat4 " + get_uniform_name() + ";\n";
+ String code = _get_qual_str() + "uniform mat4 " + get_uniform_name();
+ if (default_value_enabled) {
+ Vector3 row0 = default_value.basis.get_row(0);
+ Vector3 row1 = default_value.basis.get_row(1);
+ Vector3 row2 = default_value.basis.get_row(2);
+ Vector3 origin = default_value.origin;
+ code += " = mat4(" + vformat("vec4(%.6f, %.6f, %.6f, 0.0)", row0.x, row0.y, row0.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row1.x, row1.y, row1.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row2.x, row2.y, row2.z) + vformat(", vec4(%.6f, %.6f, %.6f, 1.0)", origin.x, origin.y, origin.z) + ")";
+ }
+ code += ";\n";
+ return code;
}
String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+void VisualShaderNodeTransformUniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformUniform::set_default_value_enabled);
+ ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformUniform::is_default_value_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformUniform::set_default_value);
+ ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformUniform::get_default_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "default_value"), "set_default_value", "get_default_value");
+}
+
+bool VisualShaderNodeTransformUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeTransformUniform::is_use_prop_slots() const {
+ return true;
+}
+
+bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
+Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() const {
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
+ props.push_back("default_value_enabled");
+ if (default_value_enabled) {
+ props.push_back("default_value");
+ }
+ return props;
+}
+
VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() {
}
@@ -3239,7 +4187,6 @@ int VisualShaderNodeTextureUniform::get_output_port_count() const {
}
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const {
-
switch (p_port) {
case 0:
return PORT_TYPE_VECTOR;
@@ -3253,7 +4200,6 @@ VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_out
}
String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
-
switch (p_port) {
case 0:
return "rgb";
@@ -3267,30 +4213,39 @@ String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
}
String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- String code = "uniform sampler2D " + get_uniform_name();
+ String code = _get_qual_str() + "uniform sampler2D " + get_uniform_name();
switch (texture_type) {
case TYPE_DATA:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black;\n";
- else
+ } else {
code += ";\n";
+ }
break;
case TYPE_COLOR:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black_albedo;\n";
- else
+ } else {
code += " : hint_albedo;\n";
+ }
+ break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
break;
- case TYPE_NORMALMAP: code += " : hint_normal;\n"; break;
- case TYPE_ANISO: code += " : hint_aniso;\n"; break;
}
return code;
}
-String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+bool VisualShaderNodeTextureUniform::is_code_generated() const {
+ return is_output_port_connected(0) || is_output_port_connected(1); // rgb or alpha
+}
+String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String id = get_uniform_name();
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -3313,7 +4268,6 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual
}
void VisualShaderNodeTextureUniform::set_texture_type(TextureType p_type) {
-
texture_type = p_type;
emit_changed();
}
@@ -3332,7 +4286,7 @@ VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get
}
Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const {
- Vector<StringName> props;
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("texture_type");
props.push_back("color_default");
return props;
@@ -3364,9 +4318,19 @@ String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) c
return "";
}
+bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) const {
+ switch (p_qual) {
+ case Qualifier::QUAL_NONE:
+ return true;
+ case Qualifier::QUAL_GLOBAL:
+ return true;
+ case Qualifier::QUAL_INSTANCE:
+ return false;
+ }
+ return false;
+}
+
VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
- texture_type = TYPE_DATA;
- color_default = COLOR_DEFAULT_WHITE;
simple_decl = false;
}
@@ -3399,7 +4363,6 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port)
}
String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
String code;
code += "// TRIPLANAR FUNCTION GLOBAL CODE\n";
@@ -3422,11 +4385,9 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader:
}
String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
String code;
if (p_type == VisualShader::TYPE_VERTEX) {
-
code += "\t// TRIPLANAR FUNCTION VERTEX CODE\n";
code += "\t\ttriplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n";
code += "\t\ttriplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n";
@@ -3438,18 +4399,17 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader:
}
String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String id = get_uniform_name();
String code = "\t{\n";
if (p_input_vars[0] == String() && p_input_vars[1] == String()) {
- code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal, triplanar_pos );\n";
+ code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, triplanar_pos);\n";
} else if (p_input_vars[0] != String() && p_input_vars[1] == String()) {
- code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", " + p_input_vars[0] + ", triplanar_pos );\n";
+ code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", triplanar_pos);\n";
} else if (p_input_vars[0] == String() && p_input_vars[1] != String()) {
- code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal," + p_input_vars[1] + " );\n";
+ code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, " + p_input_vars[1] + ");\n";
} else {
- code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n";
+ code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
code += "\t\t" + p_output_vars[0] + " = n_tex_read.rgb;\n";
@@ -3471,42 +4431,110 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_default_hint(int
VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() {
}
-////////////// CubeMap Uniform
+////////////// Texture2DArray Uniform
-String VisualShaderNodeCubeMapUniform::get_caption() const {
- return "CubeMapUniform";
+String VisualShaderNodeTexture2DArrayUniform::get_caption() const {
+ return "Texture2DArrayUniform";
}
-int VisualShaderNodeCubeMapUniform::get_output_port_count() const {
+int VisualShaderNodeTexture2DArrayUniform::get_output_port_count() const {
return 1;
}
-VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const {
+VisualShaderNodeTexture2DArrayUniform::PortType VisualShaderNodeTexture2DArrayUniform::get_output_port_type(int p_port) const {
return PORT_TYPE_SAMPLER;
}
-String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const {
- return "samplerCube";
+String VisualShaderNodeTexture2DArrayUniform::get_output_port_name(int p_port) const {
+ return "sampler2DArray";
+}
+
+int VisualShaderNodeTexture2DArrayUniform::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeTexture2DArrayUniform::PortType VisualShaderNodeTexture2DArrayUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeTexture2DArrayUniform::get_input_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTexture2DArrayUniform::get_input_port_default_hint(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = _get_qual_str() + "uniform sampler2DArray " + get_uniform_name();
+
+ switch (texture_type) {
+ case TYPE_DATA:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black;\n";
+ else
+ code += ";\n";
+ break;
+ case TYPE_COLOR:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black_albedo;\n";
+ else
+ code += " : hint_albedo;\n";
+ break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
+ break;
+ }
+
+ return code;
+}
+
+String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return String();
+}
+
+VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() {
+}
+
+////////////// Texture3D Uniform
+
+String VisualShaderNodeTexture3DUniform::get_caption() const {
+ return "Texture3DUniform";
+}
+
+int VisualShaderNodeTexture3DUniform::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SAMPLER;
}
-int VisualShaderNodeCubeMapUniform::get_input_port_count() const {
+String VisualShaderNodeTexture3DUniform::get_output_port_name(int p_port) const {
+ return "sampler3D";
+}
+
+int VisualShaderNodeTexture3DUniform::get_input_port_count() const {
return 0;
}
-VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const {
+VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const {
+String VisualShaderNodeTexture3DUniform::get_input_port_name(int p_port) const {
return "";
}
-String VisualShaderNodeCubeMapUniform::get_input_port_default_hint(int p_port) const {
+String VisualShaderNodeTexture3DUniform::get_input_port_default_hint(int p_port) const {
return "";
}
-String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- String code = "uniform samplerCube " + get_uniform_name();
+String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = _get_qual_str() + "uniform sampler3D " + get_uniform_name();
switch (texture_type) {
case TYPE_DATA:
@@ -3521,18 +4549,92 @@ String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, Visu
else
code += " : hint_albedo;\n";
break;
- case TYPE_NORMALMAP: code += " : hint_normal;\n"; break;
- case TYPE_ANISO: code += " : hint_aniso;\n"; break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
+ break;
+ }
+
+ return code;
+}
+
+String VisualShaderNodeTexture3DUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return String();
+}
+
+VisualShaderNodeTexture3DUniform::VisualShaderNodeTexture3DUniform() {
+}
+
+////////////// Cubemap Uniform
+
+String VisualShaderNodeCubemapUniform::get_caption() const {
+ return "CubemapUniform";
+}
+
+int VisualShaderNodeCubemapUniform::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeCubemapUniform::PortType VisualShaderNodeCubemapUniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SAMPLER;
+}
+
+String VisualShaderNodeCubemapUniform::get_output_port_name(int p_port) const {
+ return "samplerCube";
+}
+
+int VisualShaderNodeCubemapUniform::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeCubemapUniform::PortType VisualShaderNodeCubemapUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeCubemapUniform::get_input_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeCubemapUniform::get_input_port_default_hint(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = _get_qual_str() + "uniform samplerCube " + get_uniform_name();
+
+ switch (texture_type) {
+ case TYPE_DATA:
+ if (color_default == COLOR_DEFAULT_BLACK) {
+ code += " : hint_black;\n";
+ } else {
+ code += ";\n";
+ }
+ break;
+ case TYPE_COLOR:
+ if (color_default == COLOR_DEFAULT_BLACK) {
+ code += " : hint_black_albedo;\n";
+ } else {
+ code += " : hint_albedo;\n";
+ }
+ break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
+ break;
}
return code;
}
-String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeCubemapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return String();
}
-VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() {
+VisualShaderNodeCubemapUniform::VisualShaderNodeCubemapUniform() {
}
////////////// If
@@ -3584,7 +4686,6 @@ String VisualShaderNodeIf::get_output_port_name(int p_port) const {
}
String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
code += "\tif(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ")\n"; // abs(a - b) < tolerance eg. a == b
code += "\t{\n";
@@ -3602,13 +4703,13 @@ String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type
}
VisualShaderNodeIf::VisualShaderNodeIf() {
+ simple_decl = false;
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, CMP_EPSILON);
set_input_port_default_value(3, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(4, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(5, Vector3(0.0, 0.0, 0.0));
- simple_decl = false;
}
////////////// Switch
@@ -3654,7 +4755,6 @@ String VisualShaderNodeSwitch::get_output_port_name(int p_port) const {
}
String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
code += "\tif(" + p_input_vars[0] + ")\n";
code += "\t{\n";
@@ -3668,10 +4768,10 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::
}
VisualShaderNodeSwitch::VisualShaderNodeSwitch() {
+ simple_decl = false;
set_input_port_default_value(0, false);
set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
- simple_decl = false;
}
////////////// Switch(scalar)
@@ -3749,8 +4849,14 @@ String VisualShaderNodeFresnel::get_output_port_name(int p_port) const {
return "result";
}
-String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const {
+ if (p_port == 2) {
+ return false;
+ }
+ return true;
+}
+String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String normal;
String view;
if (p_input_vars[0] == String()) {
@@ -3764,7 +4870,15 @@ String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader:
view = p_input_vars[1];
}
- return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
+ if (is_input_port_connected(2)) {
+ return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
+ } else {
+ if (get_input_port_default_value(2)) {
+ return "\t" + p_output_vars[0] + " = pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
+ } else {
+ return "\t" + p_output_vars[0] + " = pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
+ }
+ }
}
String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const {
@@ -3784,42 +4898,34 @@ VisualShaderNodeFresnel::VisualShaderNodeFresnel() {
////////////// Is
String VisualShaderNodeIs::get_caption() const {
-
return "Is";
}
int VisualShaderNodeIs::get_input_port_count() const {
-
return 1;
}
VisualShaderNodeIs::PortType VisualShaderNodeIs::get_input_port_type(int p_port) const {
-
return PORT_TYPE_SCALAR;
}
String VisualShaderNodeIs::get_input_port_name(int p_port) const {
-
return "";
}
int VisualShaderNodeIs::get_output_port_count() const {
-
return 1;
}
VisualShaderNodeIs::PortType VisualShaderNodeIs::get_output_port_type(int p_port) const {
-
return PORT_TYPE_BOOLEAN;
}
String VisualShaderNodeIs::get_output_port_name(int p_port) const {
-
return "";
}
String VisualShaderNodeIs::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_IS_NAN + 1] = {
"isinf($)",
"isnan($)"
@@ -3831,25 +4937,21 @@ String VisualShaderNodeIs::generate_code(Shader::Mode p_mode, VisualShader::Type
}
void VisualShaderNodeIs::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeIs::Function VisualShaderNodeIs::get_function() const {
-
return func;
}
Vector<StringName> VisualShaderNodeIs::get_editable_properties() const {
-
Vector<StringName> props;
props.push_back("function");
return props;
}
void VisualShaderNodeIs::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIs::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIs::get_function);
@@ -3860,20 +4962,16 @@ void VisualShaderNodeIs::_bind_methods() {
}
VisualShaderNodeIs::VisualShaderNodeIs() {
-
- func = FUNC_IS_INF;
set_input_port_default_value(0, 0.0);
}
////////////// Compare
String VisualShaderNodeCompare::get_caption() const {
-
return "Compare";
}
int VisualShaderNodeCompare::get_input_port_count() const {
-
if (ctype == CTYPE_SCALAR && (func == FUNC_EQUAL || func == FUNC_NOT_EQUAL)) {
return 3;
}
@@ -3881,12 +4979,14 @@ int VisualShaderNodeCompare::get_input_port_count() const {
}
VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const {
-
- if (p_port == 2)
+ if (p_port == 2) {
return PORT_TYPE_SCALAR;
+ }
switch (ctype) {
case CTYPE_SCALAR:
return PORT_TYPE_SCALAR;
+ case CTYPE_SCALAR_INT:
+ return PORT_TYPE_SCALAR_INT;
case CTYPE_VECTOR:
return PORT_TYPE_VECTOR;
case CTYPE_BOOLEAN:
@@ -3898,12 +4998,13 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i
}
String VisualShaderNodeCompare::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "a";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "b";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "tolerance";
+ }
return "";
}
@@ -3916,13 +5017,13 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_output_port_type(
}
String VisualShaderNodeCompare::get_output_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "result";
+ }
return "";
}
String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
-
if (ctype == CTYPE_BOOLEAN || ctype == CTYPE_TRANSFORM) {
if (func > FUNC_NOT_EQUAL) {
return TTR("Invalid comparison function for that type.");
@@ -3933,7 +5034,6 @@ String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::T
}
String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *ops[FUNC_LESS_THAN_EQUAL + 1] = {
"==",
"!=",
@@ -3965,10 +5065,14 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
} else if (func == FUNC_NOT_EQUAL) {
code += "\t" + p_output_vars[0] + " = !(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");";
} else {
- code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n";
+ code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n";
}
break;
+ case CTYPE_SCALAR_INT:
+ code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n";
+ break;
+
case CTYPE_VECTOR:
code += "\t{\n";
code += "\t\tbvec3 _bv = " + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n";
@@ -3977,14 +5081,16 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
break;
case CTYPE_BOOLEAN:
- if (func > FUNC_NOT_EQUAL)
+ if (func > FUNC_NOT_EQUAL) {
return "\t" + p_output_vars[0] + " = false;\n";
+ }
code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n";
break;
case CTYPE_TRANSFORM:
- if (func > FUNC_NOT_EQUAL)
+ if (func > FUNC_NOT_EQUAL) {
return "\t" + p_output_vars[0] + " = false;\n";
+ }
code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n";
break;
@@ -3995,7 +5101,6 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
}
void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) {
-
ctype = p_type;
switch (ctype) {
@@ -4004,6 +5109,11 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) {
set_input_port_default_value(1, 0.0);
simple_decl = true;
break;
+ case CTYPE_SCALAR_INT:
+ set_input_port_default_value(0, 0);
+ set_input_port_default_value(1, 0);
+ simple_decl = true;
+ break;
case CTYPE_VECTOR:
set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
@@ -4024,29 +5134,24 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) {
}
VisualShaderNodeCompare::ComparisonType VisualShaderNodeCompare::get_comparison_type() const {
-
return ctype;
}
void VisualShaderNodeCompare::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeCompare::Function VisualShaderNodeCompare::get_function() const {
-
return func;
}
void VisualShaderNodeCompare::set_condition(Condition p_cond) {
-
condition = p_cond;
emit_changed();
}
VisualShaderNodeCompare::Condition VisualShaderNodeCompare::get_condition() const {
-
return condition;
}
@@ -4054,13 +5159,13 @@ Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const {
Vector<StringName> props;
props.push_back("type");
props.push_back("function");
- if (ctype == CTYPE_VECTOR)
+ if (ctype == CTYPE_VECTOR) {
props.push_back("condition");
+ }
return props;
}
void VisualShaderNodeCompare::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_comparison_type", "type"), &VisualShaderNodeCompare::set_comparison_type);
ClassDB::bind_method(D_METHOD("get_comparison_type"), &VisualShaderNodeCompare::get_comparison_type);
@@ -4070,11 +5175,12 @@ void VisualShaderNodeCompare::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition);
ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function");
ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition");
BIND_ENUM_CONSTANT(CTYPE_SCALAR);
+ BIND_ENUM_CONSTANT(CTYPE_SCALAR_INT);
BIND_ENUM_CONSTANT(CTYPE_VECTOR);
BIND_ENUM_CONSTANT(CTYPE_BOOLEAN);
BIND_ENUM_CONSTANT(CTYPE_TRANSFORM);
@@ -4091,10 +5197,99 @@ void VisualShaderNodeCompare::_bind_methods() {
}
VisualShaderNodeCompare::VisualShaderNodeCompare() {
- ctype = CTYPE_SCALAR;
- func = FUNC_EQUAL;
- condition = COND_ALL;
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, CMP_EPSILON);
}
+
+////////////// Fma
+
+String VisualShaderNodeMultiplyAdd::get_caption() const {
+ return "MultiplyAdd";
+}
+
+int VisualShaderNodeMultiplyAdd::get_input_port_count() const {
+ return 3;
+}
+
+VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const {
+ if (type == TYPE_SCALAR) {
+ return PORT_TYPE_SCALAR;
+ }
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeMultiplyAdd::get_input_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "a";
+ } else if (p_port == 1) {
+ return "b(*)";
+ } else if (p_port == 2) {
+ return "c(+)";
+ }
+ return "";
+}
+
+int VisualShaderNodeMultiplyAdd::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_output_port_type(int p_port) const {
+ if (type == TYPE_SCALAR) {
+ return PORT_TYPE_SCALAR;
+ } else {
+ return PORT_TYPE_VECTOR;
+ }
+}
+
+String VisualShaderNodeMultiplyAdd::get_output_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeMultiplyAdd::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = fma(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+}
+
+void VisualShaderNodeMultiplyAdd::set_type(Type p_type) {
+ ERR_FAIL_INDEX((int)p_type, TYPE_MAX);
+ if (p_type != type) {
+ if (p_type == TYPE_SCALAR) {
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, 0.0);
+ } else {
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+ }
+ }
+ type = p_type;
+ emit_changed();
+}
+
+VisualShaderNodeMultiplyAdd::Type VisualShaderNodeMultiplyAdd::get_type() const {
+ return type;
+}
+
+Vector<StringName> VisualShaderNodeMultiplyAdd::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("type");
+ return props;
+}
+
+void VisualShaderNodeMultiplyAdd::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_type", "type"), &VisualShaderNodeMultiplyAdd::set_type);
+ ClassDB::bind_method(D_METHOD("get_type"), &VisualShaderNodeMultiplyAdd::get_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_type", "get_type");
+
+ BIND_ENUM_CONSTANT(TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(TYPE_MAX);
+}
+
+VisualShaderNodeMultiplyAdd::VisualShaderNodeMultiplyAdd() {
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, 0.0);
+}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index cca37273d9..1c986d1ef4 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -37,60 +37,90 @@
/// CONSTANTS
///////////////////////////////////////
-class VisualShaderNodeScalarConstant : public VisualShaderNode {
- GDCLASS(VisualShaderNodeScalarConstant, VisualShaderNode);
- float constant;
+class VisualShaderNodeFloatConstant : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNode);
+ float constant = 0.0f;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_constant(float p_value);
float get_constant() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
- VisualShaderNodeScalarConstant();
+ VisualShaderNodeFloatConstant();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeIntConstant : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeIntConstant, VisualShaderNode);
+ int constant = 0;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_constant(int p_value);
+ int get_constant() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeIntConstant();
};
///////////////////////////////////////
class VisualShaderNodeBooleanConstant : public VisualShaderNode {
GDCLASS(VisualShaderNodeBooleanConstant, VisualShaderNode);
- bool constant;
+ bool constant = false;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_constant(bool p_value);
bool get_constant() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeBooleanConstant();
};
@@ -99,28 +129,28 @@ public:
class VisualShaderNodeColorConstant : public VisualShaderNode {
GDCLASS(VisualShaderNodeColorConstant, VisualShaderNode);
- Color constant;
+ Color constant = Color(1, 1, 1, 1);
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_constant(Color p_value);
Color get_constant() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeColorConstant();
};
@@ -135,22 +165,22 @@ protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_constant(Vector3 p_value);
Vector3 get_constant() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeVec3Constant();
};
@@ -165,22 +195,22 @@ protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_constant(Transform p_value);
Transform get_constant() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeTransformConstant();
};
@@ -191,7 +221,7 @@ public:
class VisualShaderNodeTexture : public VisualShaderNode {
GDCLASS(VisualShaderNodeTexture, VisualShaderNode);
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
public:
enum Source {
@@ -206,45 +236,45 @@ public:
enum TextureType {
TYPE_DATA,
TYPE_COLOR,
- TYPE_NORMALMAP
+ TYPE_NORMALMAP,
};
private:
- Source source;
- TextureType texture_type;
+ Source source = SOURCE_TEXTURE;
+ TextureType texture_type = TYPE_DATA;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String get_input_port_default_hint(int p_port) const;
+ virtual String get_input_port_default_hint(int p_port) const override;
- virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_source(Source p_source);
Source get_source() const;
- void set_texture(Ref<Texture> p_value);
- Ref<Texture> get_texture() const;
+ void set_texture(Ref<Texture2D> p_value);
+ Ref<Texture2D> get_texture() const;
void set_texture_type(TextureType p_type);
TextureType get_texture_type() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
- virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
VisualShaderNodeTexture();
};
@@ -254,9 +284,91 @@ VARIANT_ENUM_CAST(VisualShaderNodeTexture::Source)
///////////////////////////////////////
-class VisualShaderNodeCubeMap : public VisualShaderNode {
- GDCLASS(VisualShaderNodeCubeMap, VisualShaderNode);
- Ref<CubeMap> cube_map;
+class VisualShaderNodeSample3D : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeSample3D, VisualShaderNode);
+
+public:
+ enum Source {
+ SOURCE_TEXTURE,
+ SOURCE_PORT,
+ };
+
+protected:
+ Source source = SOURCE_TEXTURE;
+
+ static void _bind_methods();
+
+public:
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+ virtual String get_input_port_default_hint(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_source(Source p_source);
+ Source get_source() const;
+
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
+
+ VisualShaderNodeSample3D();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeSample3D::Source)
+
+class VisualShaderNodeTexture2DArray : public VisualShaderNodeSample3D {
+ GDCLASS(VisualShaderNodeTexture2DArray, VisualShaderNodeSample3D);
+ Ref<Texture2DArray> texture;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+
+ void set_texture_array(Ref<Texture2DArray> p_value);
+ Ref<Texture2DArray> get_texture_array() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeTexture2DArray();
+};
+
+class VisualShaderNodeTexture3D : public VisualShaderNodeSample3D {
+ GDCLASS(VisualShaderNodeTexture3D, VisualShaderNodeSample3D);
+ Ref<Texture3D> texture;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+
+ void set_texture(Ref<Texture3D> p_value);
+ Ref<Texture3D> get_texture() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeTexture3D();
+};
+
+class VisualShaderNodeCubemap : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeCubemap, VisualShaderNode);
+ Ref<Cubemap> cube_map;
public:
enum Source {
@@ -271,51 +383,51 @@ public:
};
private:
- Source source;
- TextureType texture_type;
+ Source source = SOURCE_TEXTURE;
+ TextureType texture_type = TYPE_DATA;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
- virtual String get_input_port_default_hint(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+ virtual String get_input_port_default_hint(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_source(Source p_source);
Source get_source() const;
- void set_cube_map(Ref<CubeMap> p_value);
- Ref<CubeMap> get_cube_map() const;
+ void set_cube_map(Ref<Cubemap> p_value);
+ Ref<Cubemap> get_cube_map() const;
void set_texture_type(TextureType p_type);
TextureType get_texture_type() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
- VisualShaderNodeCubeMap();
+ VisualShaderNodeCubemap();
};
-VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::TextureType)
-VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::Source)
+VARIANT_ENUM_CAST(VisualShaderNodeCubemap::TextureType)
+VARIANT_ENUM_CAST(VisualShaderNodeCubemap::Source)
///////////////////////////////////////
/// OPS
///////////////////////////////////////
-class VisualShaderNodeScalarOp : public VisualShaderNode {
- GDCLASS(VisualShaderNodeScalarOp, VisualShaderNode);
+class VisualShaderNodeFloatOp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeFloatOp, VisualShaderNode);
public:
enum Operator {
@@ -332,32 +444,74 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_ADD;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_operator(Operator p_op);
Operator get_operator() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
- VisualShaderNodeScalarOp();
+ VisualShaderNodeFloatOp();
};
-VARIANT_ENUM_CAST(VisualShaderNodeScalarOp::Operator)
+VARIANT_ENUM_CAST(VisualShaderNodeFloatOp::Operator)
+
+class VisualShaderNodeIntOp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeIntOp, VisualShaderNode);
+
+public:
+ enum Operator {
+ OP_ADD,
+ OP_SUB,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_MAX,
+ OP_MIN,
+ };
+
+protected:
+ Operator op = OP_ADD;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_operator(Operator p_op);
+ Operator get_operator() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeIntOp();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeIntOp::Operator)
class VisualShaderNodeVectorOp : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorOp, VisualShaderNode);
@@ -379,27 +533,27 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_ADD;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_operator(Operator p_op);
Operator get_operator() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeVectorOp();
};
@@ -425,27 +579,27 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_SCREEN;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_operator(Operator p_op);
Operator get_operator() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeColorOp();
};
@@ -468,27 +622,27 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_AxB;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_operator(Operator p_op);
Operator get_operator() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeTransformMult();
};
@@ -511,27 +665,27 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_AxB;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_operator(Operator p_op);
Operator get_operator() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeTransformVecMult();
};
@@ -539,11 +693,11 @@ public:
VARIANT_ENUM_CAST(VisualShaderNodeTransformVecMult::Operator)
///////////////////////////////////////
-/// SCALAR FUNC
+/// FLOAT FUNC
///////////////////////////////////////
-class VisualShaderNodeScalarFunc : public VisualShaderNode {
- GDCLASS(VisualShaderNodeScalarFunc, VisualShaderNode);
+class VisualShaderNodeFloatFunc : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeFloatFunc, VisualShaderNode);
public:
enum Function {
@@ -582,32 +736,75 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_SIGN;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_function(Function p_func);
Function get_function() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
- VisualShaderNodeScalarFunc();
+ VisualShaderNodeFloatFunc();
};
-VARIANT_ENUM_CAST(VisualShaderNodeScalarFunc::Function)
+VARIANT_ENUM_CAST(VisualShaderNodeFloatFunc::Function)
+
+///////////////////////////////////////
+/// INT FUNC
+///////////////////////////////////////
+
+class VisualShaderNodeIntFunc : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeIntFunc, VisualShaderNode);
+
+public:
+ enum Function {
+ FUNC_ABS,
+ FUNC_CLAMP,
+ FUNC_NEGATE,
+ FUNC_SIGN,
+ };
+
+protected:
+ Function func = FUNC_SIGN;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_function(Function p_func);
+ Function get_function() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeIntFunc();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeIntFunc::Function)
///////////////////////////////////////
/// VECTOR FUNC
@@ -656,27 +853,27 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_NORMALIZE;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_function(Function p_func);
Function get_function() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeVectorFunc();
};
@@ -697,27 +894,27 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_GRAYSCALE;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_function(Function p_func);
Function get_function() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeColorFunc();
};
@@ -738,27 +935,27 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_INVERSE;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_function(Function p_func);
Function get_function() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeTransformFunc();
};
@@ -773,17 +970,17 @@ class VisualShaderNodeDotProduct : public VisualShaderNode {
GDCLASS(VisualShaderNodeDotProduct, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeDotProduct();
};
@@ -796,17 +993,17 @@ class VisualShaderNodeVectorLen : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorLen, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorLen();
};
@@ -819,17 +1016,17 @@ class VisualShaderNodeDeterminant : public VisualShaderNode {
GDCLASS(VisualShaderNodeDeterminant, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeDeterminant();
};
@@ -842,17 +1039,17 @@ class VisualShaderNodeScalarClamp : public VisualShaderNode {
GDCLASS(VisualShaderNodeScalarClamp, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeScalarClamp();
};
@@ -863,17 +1060,17 @@ class VisualShaderNodeVectorClamp : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorClamp, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorClamp();
};
@@ -893,27 +1090,27 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_SUM;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_function(Function p_func);
Function get_function() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeScalarDerivativeFunc();
};
@@ -933,27 +1130,27 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_SUM;
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_function(Function p_func);
Function get_function() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeVectorDerivativeFunc();
};
@@ -968,17 +1165,17 @@ class VisualShaderNodeFaceForward : public VisualShaderNode {
GDCLASS(VisualShaderNodeFaceForward, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeFaceForward();
};
@@ -991,17 +1188,17 @@ class VisualShaderNodeOuterProduct : public VisualShaderNode {
GDCLASS(VisualShaderNodeOuterProduct, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeOuterProduct();
};
@@ -1014,17 +1211,17 @@ class VisualShaderNodeVectorScalarStep : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorScalarStep, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorScalarStep();
};
@@ -1037,17 +1234,17 @@ class VisualShaderNodeScalarSmoothStep : public VisualShaderNode {
GDCLASS(VisualShaderNodeScalarSmoothStep, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeScalarSmoothStep();
};
@@ -1058,17 +1255,17 @@ class VisualShaderNodeVectorSmoothStep : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorSmoothStep, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorSmoothStep();
};
@@ -1079,17 +1276,17 @@ class VisualShaderNodeVectorScalarSmoothStep : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorScalarSmoothStep, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorScalarSmoothStep();
};
@@ -1102,17 +1299,17 @@ class VisualShaderNodeVectorDistance : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorDistance, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorDistance();
};
@@ -1125,17 +1322,17 @@ class VisualShaderNodeVectorRefract : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorRefract, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorRefract();
};
@@ -1148,17 +1345,17 @@ class VisualShaderNodeScalarInterp : public VisualShaderNode {
GDCLASS(VisualShaderNodeScalarInterp, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeScalarInterp();
};
@@ -1169,17 +1366,17 @@ class VisualShaderNodeVectorInterp : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorInterp, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorInterp();
};
@@ -1190,17 +1387,17 @@ class VisualShaderNodeVectorScalarMix : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorScalarMix, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorScalarMix();
};
@@ -1213,17 +1410,17 @@ class VisualShaderNodeVectorCompose : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorCompose, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorCompose();
};
@@ -1234,17 +1431,17 @@ class VisualShaderNodeTransformCompose : public VisualShaderNode {
GDCLASS(VisualShaderNodeTransformCompose, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeTransformCompose();
};
@@ -1257,17 +1454,17 @@ class VisualShaderNodeVectorDecompose : public VisualShaderNode {
GDCLASS(VisualShaderNodeVectorDecompose, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeVectorDecompose();
};
@@ -1278,17 +1475,17 @@ class VisualShaderNodeTransformDecompose : public VisualShaderNode {
GDCLASS(VisualShaderNodeTransformDecompose, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeTransformDecompose();
};
@@ -1297,44 +1494,174 @@ public:
/// UNIFORMS
///////////////////////////////////////
-class VisualShaderNodeScalarUniform : public VisualShaderNodeUniform {
- GDCLASS(VisualShaderNodeScalarUniform, VisualShaderNodeUniform);
+class VisualShaderNodeFloatUniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeFloatUniform, VisualShaderNodeUniform);
public:
- virtual String get_caption() const;
+ enum Hint {
+ HINT_NONE,
+ HINT_RANGE,
+ HINT_RANGE_STEP,
+ };
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+private:
+ Hint hint = HINT_NONE;
+ float hint_range_min = 0.0f;
+ float hint_range_max = 1.0f;
+ float hint_range_step = 0.1f;
+ bool default_value_enabled = false;
+ float default_value = 0.0f;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+protected:
+ static void _bind_methods();
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
+ void set_hint(Hint p_hint);
+ Hint get_hint() const;
+
+ void set_min(float p_value);
+ float get_min() const;
+
+ void set_max(float p_value);
+ float get_max() const;
- VisualShaderNodeScalarUniform();
+ void set_step(float p_value);
+ float get_step() const;
+
+ void set_default_value_enabled(bool p_enabled);
+ bool is_default_value_enabled() const;
+
+ void set_default_value(float p_value);
+ float get_default_value() const;
+
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeFloatUniform();
};
+VARIANT_ENUM_CAST(VisualShaderNodeFloatUniform::Hint)
+
+class VisualShaderNodeIntUniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeIntUniform, VisualShaderNodeUniform);
+
+public:
+ enum Hint {
+ HINT_NONE,
+ HINT_RANGE,
+ HINT_RANGE_STEP,
+ };
+
+private:
+ Hint hint = HINT_NONE;
+ int hint_range_min = 0;
+ int hint_range_max = 100;
+ int hint_range_step = 1;
+ bool default_value_enabled = false;
+ int default_value = 0;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
+ void set_hint(Hint p_hint);
+ Hint get_hint() const;
+
+ void set_min(int p_value);
+ int get_min() const;
+
+ void set_max(int p_value);
+ int get_max() const;
+
+ void set_step(int p_value);
+ int get_step() const;
+
+ void set_default_value_enabled(bool p_enabled);
+ bool is_default_value_enabled() const;
+
+ void set_default_value(int p_value);
+ int get_default_value() const;
+
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeIntUniform();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeIntUniform::Hint)
+
///////////////////////////////////////
class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeBooleanUniform, VisualShaderNodeUniform);
+private:
+ bool default_value_enabled = false;
+ bool default_value = false;
+
+protected:
+ static void _bind_methods();
+
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
+ void set_default_value_enabled(bool p_enabled);
+ bool is_default_value_enabled() const;
+
+ void set_default_value(bool p_value);
+ bool get_default_value() const;
+
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeBooleanUniform();
};
@@ -1344,19 +1671,38 @@ public:
class VisualShaderNodeColorUniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeColorUniform, VisualShaderNodeUniform);
+private:
+ bool default_value_enabled = false;
+ Color default_value = Color(1.0, 1.0, 1.0, 1.0);
+
+protected:
+ static void _bind_methods();
+
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual bool is_show_prop_names() const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ void set_default_value_enabled(bool p_enabled);
+ bool is_default_value_enabled() const;
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ void set_default_value(const Color &p_value);
+ Color get_default_value() const;
+
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeColorUniform();
};
@@ -1366,19 +1712,39 @@ public:
class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform);
+private:
+ bool default_value_enabled = false;
+ Vector3 default_value;
+
+protected:
+ static void _bind_methods();
+
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ void set_default_value_enabled(bool p_enabled);
+ bool is_default_value_enabled() const;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ void set_default_value(const Vector3 &p_value);
+ Vector3 get_default_value() const;
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeVec3Uniform();
};
@@ -1388,19 +1754,39 @@ public:
class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeTransformUniform, VisualShaderNodeUniform);
+private:
+ bool default_value_enabled = false;
+ Transform default_value = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
+
+protected:
+ static void _bind_methods();
+
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
+ void set_default_value_enabled(bool p_enabled);
+ bool is_default_value_enabled() const;
+
+ void set_default_value(const Transform &p_value);
+ Transform get_default_value() const;
+
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeTransformUniform();
};
@@ -1424,28 +1810,30 @@ public:
};
protected:
- TextureType texture_type;
- ColorDefault color_default;
+ TextureType texture_type = TYPE_DATA;
+ ColorDefault color_default = COLOR_DEFAULT_WHITE;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
- virtual String get_input_port_default_hint(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+ virtual String get_input_port_default_hint(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- Vector<StringName> get_editable_properties() const;
+ virtual bool is_code_generated() const override;
+
+ Vector<StringName> get_editable_properties() const override;
void set_texture_type(TextureType p_type);
TextureType get_texture_type() const;
@@ -1453,6 +1841,8 @@ public:
void set_color_default(ColorDefault p_default);
ColorDefault get_color_default() const;
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+
VisualShaderNodeTextureUniform();
};
@@ -1465,42 +1855,88 @@ class VisualShaderNodeTextureUniformTriplanar : public VisualShaderNodeTextureUn
GDCLASS(VisualShaderNodeTextureUniformTriplanar, VisualShaderNodeTextureUniform);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual String get_input_port_default_hint(int p_port) const;
+ virtual String get_input_port_default_hint(int p_port) const override;
- virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
VisualShaderNodeTextureUniformTriplanar();
};
///////////////////////////////////////
-class VisualShaderNodeCubeMapUniform : public VisualShaderNodeTextureUniform {
- GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNodeTextureUniform);
+class VisualShaderNodeTexture2DArrayUniform : public VisualShaderNodeTextureUniform {
+ GDCLASS(VisualShaderNodeTexture2DArrayUniform, VisualShaderNodeTextureUniform);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String get_input_port_default_hint(int p_port) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeTexture2DArrayUniform();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeTexture3DUniform : public VisualShaderNodeTextureUniform {
+ GDCLASS(VisualShaderNodeTexture3DUniform, VisualShaderNodeTextureUniform);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String get_input_port_default_hint(int p_port) const;
- virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String get_input_port_default_hint(int p_port) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeCubeMapUniform();
+ VisualShaderNodeTexture3DUniform();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform {
+ GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String get_input_port_default_hint(int p_port) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeCubemapUniform();
};
///////////////////////////////////////
@@ -1511,17 +1947,17 @@ class VisualShaderNodeIf : public VisualShaderNode {
GDCLASS(VisualShaderNodeIf, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeIf();
};
@@ -1534,17 +1970,17 @@ class VisualShaderNodeSwitch : public VisualShaderNode {
GDCLASS(VisualShaderNodeSwitch, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeSwitch();
};
@@ -1553,10 +1989,10 @@ class VisualShaderNodeScalarSwitch : public VisualShaderNodeSwitch {
GDCLASS(VisualShaderNodeScalarSwitch, VisualShaderNodeSwitch);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual PortType get_input_port_type(int p_port) const;
- virtual PortType get_output_port_type(int p_port) const;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual PortType get_output_port_type(int p_port) const override;
VisualShaderNodeScalarSwitch();
};
@@ -1569,18 +2005,19 @@ class VisualShaderNodeFresnel : public VisualShaderNode {
GDCLASS(VisualShaderNodeFresnel, VisualShaderNode);
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String get_input_port_default_hint(int p_port) const;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String get_input_port_default_hint(int p_port) const override;
+ virtual bool is_generate_input_var(int p_port) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeFresnel();
};
@@ -1599,28 +2036,28 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_IS_INF;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_function(Function p_func);
Function get_function() const;
- virtual Vector<StringName> get_editable_properties() const;
+ virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeIs();
};
@@ -1637,9 +2074,10 @@ class VisualShaderNodeCompare : public VisualShaderNode {
public:
enum ComparisonType {
CTYPE_SCALAR,
+ CTYPE_SCALAR_INT,
CTYPE_VECTOR,
CTYPE_BOOLEAN,
- CTYPE_TRANSFORM
+ CTYPE_TRANSFORM,
};
enum Function {
@@ -1657,25 +2095,25 @@ public:
};
protected:
- ComparisonType ctype;
- Function func;
- Condition condition;
+ ComparisonType ctype = CTYPE_SCALAR;
+ Function func = FUNC_EQUAL;
+ Condition condition = COND_ALL;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- virtual int get_input_port_count() const;
- virtual PortType get_input_port_type(int p_port) const;
- virtual String get_input_port_name(int p_port) const;
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
- virtual int get_output_port_count() const;
- virtual PortType get_output_port_type(int p_port) const;
- virtual String get_output_port_name(int p_port) const;
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
void set_comparison_type(ComparisonType p_type);
ComparisonType get_comparison_type() const;
@@ -1686,8 +2124,8 @@ public:
void set_condition(Condition p_cond);
Condition get_condition() const;
- virtual Vector<StringName> get_editable_properties() const;
- virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
+ virtual Vector<StringName> get_editable_properties() const override;
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
VisualShaderNodeCompare();
};
@@ -1696,4 +2134,43 @@ VARIANT_ENUM_CAST(VisualShaderNodeCompare::ComparisonType)
VARIANT_ENUM_CAST(VisualShaderNodeCompare::Function)
VARIANT_ENUM_CAST(VisualShaderNodeCompare::Condition)
+class VisualShaderNodeMultiplyAdd : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeMultiplyAdd, VisualShaderNode);
+
+public:
+ enum Type {
+ TYPE_SCALAR,
+ TYPE_VECTOR,
+ TYPE_MAX,
+ };
+
+protected:
+ Type type = TYPE_SCALAR;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_type(Type p_type);
+ Type get_type() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeMultiplyAdd();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeMultiplyAdd::Type)
+
#endif // VISUAL_SHADER_NODES_H
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index 5cc809d8e3..d2bc2bea31 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -33,14 +33,12 @@
#include "core/project_settings.h"
#include "scene/2d/camera_2d.h"
#include "scene/2d/visibility_notifier_2d.h"
-#include "scene/main/viewport.h"
-#include "servers/physics_2d_server.h"
-#include "servers/visual_server.h"
+#include "scene/main/window.h"
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
struct SpatialIndexer2D {
-
struct CellRef {
-
int ref;
_FORCE_INLINE_ int inc() {
@@ -58,7 +56,6 @@ struct SpatialIndexer2D {
};
struct CellKey {
-
union {
struct {
int32_t x;
@@ -74,7 +71,6 @@ struct SpatialIndexer2D {
};
struct CellData {
-
Map<VisibilityNotifier2D *, CellRef> notifiers;
};
@@ -84,7 +80,6 @@ struct SpatialIndexer2D {
Map<VisibilityNotifier2D *, Rect2> notifiers;
struct ViewportData {
-
Map<VisibilityNotifier2D *, uint64_t> notifiers;
Rect2 rect;
};
@@ -96,30 +91,25 @@ struct SpatialIndexer2D {
uint64_t pass;
void _notifier_update_cells(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect, bool p_add) {
-
Point2i begin = p_rect.position;
begin /= cell_size;
Point2i end = p_rect.position + p_rect.size;
end /= cell_size;
for (int i = begin.x; i <= end.x; i++) {
-
for (int j = begin.y; j <= end.y; j++) {
-
CellKey ck;
ck.x = i;
ck.y = j;
Map<CellKey, CellData>::Element *E = cells.find(ck);
if (p_add) {
-
- if (!E)
+ if (!E) {
E = cells.insert(ck, CellData());
+ }
E->get().notifiers[p_notifier].inc();
} else {
-
ERR_CONTINUE(!E);
if (E->get().notifiers[p_notifier].dec() == 0) {
-
E->get().notifiers.erase(p_notifier);
if (E->get().notifiers.empty()) {
cells.erase(E);
@@ -131,7 +121,6 @@ struct SpatialIndexer2D {
}
void _notifier_add(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
-
ERR_FAIL_COND(notifiers.has(p_notifier));
notifiers[p_notifier] = p_rect;
_notifier_update_cells(p_notifier, p_rect, true);
@@ -139,11 +128,11 @@ struct SpatialIndexer2D {
}
void _notifier_update(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
-
Map<VisibilityNotifier2D *, Rect2>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
- if (E->get() == p_rect)
+ if (E->get() == p_rect) {
return;
+ }
_notifier_update_cells(p_notifier, p_rect, true);
_notifier_update_cells(p_notifier, E->get(), false);
@@ -152,7 +141,6 @@ struct SpatialIndexer2D {
}
void _notifier_remove(VisibilityNotifier2D *p_notifier) {
-
Map<VisibilityNotifier2D *, Rect2>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
_notifier_update_cells(p_notifier, E->get(), false);
@@ -160,7 +148,6 @@ struct SpatialIndexer2D {
List<Viewport *> removed;
for (Map<Viewport *, ViewportData>::Element *F = viewports.front(); F; F = F->next()) {
-
Map<VisibilityNotifier2D *, uint64_t>::Element *G = F->get().notifiers.find(p_notifier);
if (G) {
@@ -170,7 +157,6 @@ struct SpatialIndexer2D {
}
while (!removed.empty()) {
-
p_notifier->_exit_viewport(removed.front()->get());
removed.pop_front();
}
@@ -179,7 +165,6 @@ struct SpatialIndexer2D {
}
void _add_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
ERR_FAIL_COND(viewports.has(p_viewport));
ViewportData vd;
vd.rect = p_rect;
@@ -188,11 +173,11 @@ struct SpatialIndexer2D {
}
void _update_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
Map<Viewport *, ViewportData>::Element *E = viewports.find(p_viewport);
ERR_FAIL_COND(!E);
- if (E->get().rect == p_rect)
+ if (E->get().rect == p_rect) {
return;
+ }
E->get().rect = p_rect;
changed = true;
}
@@ -201,7 +186,6 @@ struct SpatialIndexer2D {
ERR_FAIL_COND(!viewports.has(p_viewport));
List<VisibilityNotifier2D *> removed;
for (Map<VisibilityNotifier2D *, uint64_t>::Element *E = viewports[p_viewport].notifiers.front(); E; E = E->next()) {
-
removed.push_back(E->key());
}
@@ -214,12 +198,11 @@ struct SpatialIndexer2D {
}
void _update() {
-
- if (!changed)
+ if (!changed) {
return;
+ }
for (Map<Viewport *, ViewportData>::Element *E = viewports.front(); E; E = E->next()) {
-
Point2i begin = E->get().rect.position;
begin /= cell_size;
Point2i end = E->get().rect.position + E->get().rect.size;
@@ -228,27 +211,25 @@ struct SpatialIndexer2D {
List<VisibilityNotifier2D *> added;
List<VisibilityNotifier2D *> removed;
- int visible_cells = (end.x - begin.x) * (end.y - begin.y);
+ uint64_t visible_cells = (uint64_t)(end.x - begin.x) * (uint64_t)(end.y - begin.y);
if (visible_cells > 10000) {
-
//well you zoomed out a lot, it's your problem. To avoid freezing in the for loops below, we'll manually check cell by cell
for (Map<CellKey, CellData>::Element *F = cells.front(); F; F = F->next()) {
-
const CellKey &ck = F->key();
- if (ck.x < begin.x || ck.x > end.x)
+ if (ck.x < begin.x || ck.x > end.x) {
continue;
- if (ck.y < begin.y || ck.y > end.y)
+ }
+ if (ck.y < begin.y || ck.y > end.y) {
continue;
+ }
//notifiers in cell
for (Map<VisibilityNotifier2D *, CellRef>::Element *G = F->get().notifiers.front(); G; G = G->next()) {
-
Map<VisibilityNotifier2D *, uint64_t>::Element *H = E->get().notifiers.find(G->key());
if (!H) {
-
H = E->get().notifiers.insert(G->key(), pass);
added.push_back(G->key());
} else {
@@ -258,12 +239,9 @@ struct SpatialIndexer2D {
}
} else {
-
//check cells in grid fashion
for (int i = begin.x; i <= end.x; i++) {
-
for (int j = begin.y; j <= end.y; j++) {
-
CellKey ck;
ck.x = i;
ck.y = j;
@@ -275,10 +253,8 @@ struct SpatialIndexer2D {
//notifiers in cell
for (Map<VisibilityNotifier2D *, CellRef>::Element *G = F->get().notifiers.front(); G; G = G->next()) {
-
Map<VisibilityNotifier2D *, uint64_t>::Element *H = E->get().notifiers.find(G->key());
if (!H) {
-
H = E->get().notifiers.insert(G->key(), pass);
added.push_back(G->key());
} else {
@@ -290,9 +266,9 @@ struct SpatialIndexer2D {
}
for (Map<VisibilityNotifier2D *, uint64_t>::Element *F = E->get().notifiers.front(); F; F = F->next()) {
-
- if (F->get() != pass)
+ if (F->get() != pass) {
removed.push_back(F->key());
+ }
}
while (!added.empty()) {
@@ -311,64 +287,55 @@ struct SpatialIndexer2D {
}
SpatialIndexer2D() {
-
pass = 0;
changed = false;
- cell_size = 100; //should be configurable with GLOBAL_DEF("") i guess
+ cell_size = GLOBAL_DEF("world/2d/cell_size", 100);
}
};
void World2D::_register_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
indexer->_add_viewport(p_viewport, p_rect);
}
void World2D::_update_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
indexer->_update_viewport(p_viewport, p_rect);
}
-void World2D::_remove_viewport(Viewport *p_viewport) {
+void World2D::_remove_viewport(Viewport *p_viewport) {
indexer->_remove_viewport(p_viewport);
}
void World2D::_register_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
-
indexer->_notifier_add(p_notifier, p_rect);
}
-void World2D::_update_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
+void World2D::_update_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
indexer->_notifier_update(p_notifier, p_rect);
}
-void World2D::_remove_notifier(VisibilityNotifier2D *p_notifier) {
+void World2D::_remove_notifier(VisibilityNotifier2D *p_notifier) {
indexer->_notifier_remove(p_notifier);
}
void World2D::_update() {
-
indexer->_update();
}
RID World2D::get_canvas() {
-
return canvas;
}
RID World2D::get_space() {
-
return space;
}
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
-
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
r_viewports->push_back(E->key());
}
}
void World2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
@@ -376,33 +343,30 @@ void World2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::_RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas");
ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "Physics2DDirectSpaceState", 0), "", "get_direct_space_state");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", 0), "", "get_direct_space_state");
}
-Physics2DDirectSpaceState *World2D::get_direct_space_state() {
-
- return Physics2DServer::get_singleton()->space_get_direct_state(space);
+PhysicsDirectSpaceState2D *World2D::get_direct_space_state() {
+ return PhysicsServer2D::get_singleton()->space_get_direct_state(space);
}
World2D::World2D() {
-
- canvas = VisualServer::get_singleton()->canvas_create();
- space = Physics2DServer::get_singleton()->space_create();
+ canvas = RenderingServer::get_singleton()->canvas_create();
+ space = PhysicsServer2D::get_singleton()->space_create();
//set space2D to be more friendly with pixels than meters, by adjusting some constants
- Physics2DServer::get_singleton()->space_set_active(space, true);
- Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98));
- Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1)));
- Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/2d/default_linear_damp", 0.1));
- ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
- Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0));
- ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+ PhysicsServer2D::get_singleton()->space_set_active(space, true);
+ PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98));
+ PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1)));
+ PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/2d/default_linear_damp", 0.1));
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+ PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0));
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
indexer = memnew(SpatialIndexer2D);
}
World2D::~World2D() {
-
- VisualServer::get_singleton()->free(canvas);
- Physics2DServer::get_singleton()->free(space);
+ RenderingServer::get_singleton()->free(canvas);
+ PhysicsServer2D::get_singleton()->free(space);
memdelete(indexer);
}
diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h
index d837ef58c2..c330719104 100644
--- a/scene/resources/world_2d.h
+++ b/scene/resources/world_2d.h
@@ -33,14 +33,13 @@
#include "core/project_settings.h"
#include "core/resource.h"
-#include "servers/physics_2d_server.h"
+#include "servers/physics_server_2d.h"
class VisibilityNotifier2D;
class Viewport;
struct SpatialIndexer2D;
class World2D : public Resource {
-
GDCLASS(World2D, Resource);
RID canvas;
@@ -67,7 +66,7 @@ public:
RID get_canvas();
RID get_space();
- Physics2DDirectSpaceState *get_direct_space_state();
+ PhysicsDirectSpaceState2D *get_direct_space_state();
void get_viewport_list(List<Viewport *> *r_viewports);
diff --git a/scene/resources/world.cpp b/scene/resources/world_3d.cpp
index 1099852098..8100f150ef 100644
--- a/scene/resources/world.cpp
+++ b/scene/resources/world_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* world.cpp */
+/* world_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,74 +28,68 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "world.h"
+#include "world_3d.h"
#include "core/math/camera_matrix.h"
#include "core/math/octree.h"
-#include "scene/3d/camera.h"
-#include "scene/3d/visibility_notifier.h"
+#include "scene/3d/camera_3d.h"
+#include "scene/3d/visibility_notifier_3d.h"
#include "scene/scene_string_names.h"
struct SpatialIndexer {
-
- Octree<VisibilityNotifier> octree;
+ Octree<VisibilityNotifier3D> octree;
struct NotifierData {
-
AABB aabb;
OctreeElementID id;
};
- Map<VisibilityNotifier *, NotifierData> notifiers;
+ Map<VisibilityNotifier3D *, NotifierData> notifiers;
struct CameraData {
-
- Map<VisibilityNotifier *, uint64_t> notifiers;
+ Map<VisibilityNotifier3D *, uint64_t> notifiers;
};
- Map<Camera *, CameraData> cameras;
+ Map<Camera3D *, CameraData> cameras;
enum {
VISIBILITY_CULL_MAX = 32768
};
- Vector<VisibilityNotifier *> cull;
+ Vector<VisibilityNotifier3D *> cull;
bool changed;
uint64_t pass;
uint64_t last_frame;
- void _notifier_add(VisibilityNotifier *p_notifier, const AABB &p_rect) {
-
+ void _notifier_add(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
ERR_FAIL_COND(notifiers.has(p_notifier));
notifiers[p_notifier].aabb = p_rect;
notifiers[p_notifier].id = octree.create(p_notifier, p_rect);
changed = true;
}
- void _notifier_update(VisibilityNotifier *p_notifier, const AABB &p_rect) {
-
- Map<VisibilityNotifier *, NotifierData>::Element *E = notifiers.find(p_notifier);
+ void _notifier_update(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
+ Map<VisibilityNotifier3D *, NotifierData>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
- if (E->get().aabb == p_rect)
+ if (E->get().aabb == p_rect) {
return;
+ }
E->get().aabb = p_rect;
octree.move(E->get().id, E->get().aabb);
changed = true;
}
- void _notifier_remove(VisibilityNotifier *p_notifier) {
-
- Map<VisibilityNotifier *, NotifierData>::Element *E = notifiers.find(p_notifier);
+ void _notifier_remove(VisibilityNotifier3D *p_notifier) {
+ Map<VisibilityNotifier3D *, NotifierData>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
octree.erase(E->get().id);
notifiers.erase(p_notifier);
- List<Camera *> removed;
- for (Map<Camera *, CameraData>::Element *F = cameras.front(); F; F = F->next()) {
-
- Map<VisibilityNotifier *, uint64_t>::Element *G = F->get().notifiers.find(p_notifier);
+ List<Camera3D *> removed;
+ for (Map<Camera3D *, CameraData>::Element *F = cameras.front(); F; F = F->next()) {
+ Map<VisibilityNotifier3D *, uint64_t>::Element *G = F->get().notifiers.find(p_notifier);
if (G) {
F->get().notifiers.erase(G);
@@ -104,7 +98,6 @@ struct SpatialIndexer {
}
while (!removed.empty()) {
-
p_notifier->_exit_camera(removed.front()->get());
removed.pop_front();
}
@@ -112,26 +105,23 @@ struct SpatialIndexer {
changed = true;
}
- void _add_camera(Camera *p_camera) {
-
+ void _add_camera(Camera3D *p_camera) {
ERR_FAIL_COND(cameras.has(p_camera));
CameraData vd;
cameras[p_camera] = vd;
changed = true;
}
- void _update_camera(Camera *p_camera) {
-
- Map<Camera *, CameraData>::Element *E = cameras.find(p_camera);
+ void _update_camera(Camera3D *p_camera) {
+ Map<Camera3D *, CameraData>::Element *E = cameras.find(p_camera);
ERR_FAIL_COND(!E);
changed = true;
}
- void _remove_camera(Camera *p_camera) {
+ void _remove_camera(Camera3D *p_camera) {
ERR_FAIL_COND(!cameras.has(p_camera));
- List<VisibilityNotifier *> removed;
- for (Map<VisibilityNotifier *, uint64_t>::Element *E = cameras[p_camera].notifiers.front(); E; E = E->next()) {
-
+ List<VisibilityNotifier3D *> removed;
+ for (Map<VisibilityNotifier3D *, uint64_t>::Element *E = cameras[p_camera].notifiers.front(); E; E = E->next()) {
removed.push_back(E->key());
}
@@ -144,36 +134,34 @@ struct SpatialIndexer {
}
void _update(uint64_t p_frame) {
-
- if (p_frame == last_frame)
+ if (p_frame == last_frame) {
return;
+ }
last_frame = p_frame;
- if (!changed)
+ if (!changed) {
return;
+ }
- for (Map<Camera *, CameraData>::Element *E = cameras.front(); E; E = E->next()) {
-
+ for (Map<Camera3D *, CameraData>::Element *E = cameras.front(); E; E = E->next()) {
pass++;
- Camera *c = E->key();
+ Camera3D *c = E->key();
Vector<Plane> planes = c->get_frustum();
int culled = octree.cull_convex(planes, cull.ptrw(), cull.size());
- VisibilityNotifier **ptr = cull.ptrw();
+ VisibilityNotifier3D **ptr = cull.ptrw();
- List<VisibilityNotifier *> added;
- List<VisibilityNotifier *> removed;
+ List<VisibilityNotifier3D *> added;
+ List<VisibilityNotifier3D *> removed;
for (int i = 0; i < culled; i++) {
-
//notifiers in frustum
- Map<VisibilityNotifier *, uint64_t>::Element *H = E->get().notifiers.find(ptr[i]);
+ Map<VisibilityNotifier3D *, uint64_t>::Element *H = E->get().notifiers.find(ptr[i]);
if (!H) {
-
E->get().notifiers.insert(ptr[i], pass);
added.push_back(ptr[i]);
} else {
@@ -181,10 +169,10 @@ struct SpatialIndexer {
}
}
- for (Map<VisibilityNotifier *, uint64_t>::Element *F = E->get().notifiers.front(); F; F = F->next()) {
-
- if (F->get() != pass)
+ for (Map<VisibilityNotifier3D *, uint64_t>::Element *F = E->get().notifiers.front(); F; F = F->next()) {
+ if (F->get() != pass) {
removed.push_back(F->key());
+ }
}
while (!added.empty()) {
@@ -202,7 +190,6 @@ struct SpatialIndexer {
}
SpatialIndexer() {
-
pass = 0;
last_frame = 0;
changed = false;
@@ -210,153 +197,157 @@ struct SpatialIndexer {
}
};
-void World::_register_camera(Camera *p_camera) {
-
+void World3D::_register_camera(Camera3D *p_camera) {
#ifndef _3D_DISABLED
indexer->_add_camera(p_camera);
#endif
}
-void World::_update_camera(Camera *p_camera) {
-
+void World3D::_update_camera(Camera3D *p_camera) {
#ifndef _3D_DISABLED
indexer->_update_camera(p_camera);
#endif
}
-void World::_remove_camera(Camera *p_camera) {
+void World3D::_remove_camera(Camera3D *p_camera) {
#ifndef _3D_DISABLED
indexer->_remove_camera(p_camera);
#endif
}
-void World::_register_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect) {
-
+void World3D::_register_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
#ifndef _3D_DISABLED
indexer->_notifier_add(p_notifier, p_rect);
#endif
}
-void World::_update_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect) {
-
+void World3D::_update_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
#ifndef _3D_DISABLED
indexer->_notifier_update(p_notifier, p_rect);
#endif
}
-void World::_remove_notifier(VisibilityNotifier *p_notifier) {
-
+void World3D::_remove_notifier(VisibilityNotifier3D *p_notifier) {
#ifndef _3D_DISABLED
indexer->_notifier_remove(p_notifier);
#endif
}
-void World::_update(uint64_t p_frame) {
-
+void World3D::_update(uint64_t p_frame) {
#ifndef _3D_DISABLED
indexer->_update(p_frame);
#endif
}
-RID World::get_space() const {
-
+RID World3D::get_space() const {
return space;
}
-RID World::get_scenario() const {
+RID World3D::get_scenario() const {
return scenario;
}
-void World::set_environment(const Ref<Environment> &p_environment) {
+void World3D::set_environment(const Ref<Environment> &p_environment) {
if (environment == p_environment) {
return;
}
environment = p_environment;
- if (environment.is_valid())
- VS::get_singleton()->scenario_set_environment(scenario, environment->get_rid());
- else
- VS::get_singleton()->scenario_set_environment(scenario, RID());
+ if (environment.is_valid()) {
+ RS::get_singleton()->scenario_set_environment(scenario, environment->get_rid());
+ } else {
+ RS::get_singleton()->scenario_set_environment(scenario, RID());
+ }
emit_changed();
}
-Ref<Environment> World::get_environment() const {
-
+Ref<Environment> World3D::get_environment() const {
return environment;
}
-void World::set_fallback_environment(const Ref<Environment> &p_environment) {
+void World3D::set_fallback_environment(const Ref<Environment> &p_environment) {
if (fallback_environment == p_environment) {
return;
}
fallback_environment = p_environment;
- if (fallback_environment.is_valid())
- VS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid());
- else
- VS::get_singleton()->scenario_set_fallback_environment(scenario, RID());
+ if (fallback_environment.is_valid()) {
+ RS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid());
+ } else {
+ RS::get_singleton()->scenario_set_fallback_environment(scenario, RID());
+ }
emit_changed();
}
-Ref<Environment> World::get_fallback_environment() const {
-
+Ref<Environment> World3D::get_fallback_environment() const {
return fallback_environment;
}
-PhysicsDirectSpaceState *World::get_direct_space_state() {
+void World3D::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) {
+ camera_effects = p_camera_effects;
+ if (camera_effects.is_valid()) {
+ RS::get_singleton()->scenario_set_camera_effects(scenario, camera_effects->get_rid());
+ } else {
+ RS::get_singleton()->scenario_set_camera_effects(scenario, RID());
+ }
+}
- return PhysicsServer::get_singleton()->space_get_direct_state(space);
+Ref<CameraEffects> World3D::get_camera_effects() const {
+ return camera_effects;
}
-void World::get_camera_list(List<Camera *> *r_cameras) {
+PhysicsDirectSpaceState3D *World3D::get_direct_space_state() {
+ return PhysicsServer3D::get_singleton()->space_get_direct_state(space);
+}
- for (Map<Camera *, SpatialIndexer::CameraData>::Element *E = indexer->cameras.front(); E; E = E->next()) {
+void World3D::get_camera_list(List<Camera3D *> *r_cameras) {
+ for (Map<Camera3D *, SpatialIndexer::CameraData>::Element *E = indexer->cameras.front(); E; E = E->next()) {
r_cameras->push_back(E->key());
}
}
-void World::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("get_space"), &World::get_space);
- ClassDB::bind_method(D_METHOD("get_scenario"), &World::get_scenario);
- ClassDB::bind_method(D_METHOD("set_environment", "env"), &World::set_environment);
- ClassDB::bind_method(D_METHOD("get_environment"), &World::get_environment);
- ClassDB::bind_method(D_METHOD("set_fallback_environment", "env"), &World::set_fallback_environment);
- ClassDB::bind_method(D_METHOD("get_fallback_environment"), &World::get_fallback_environment);
- ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World::get_direct_space_state);
+void World3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
+ ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario);
+ ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment);
+ ClassDB::bind_method(D_METHOD("get_environment"), &World3D::get_environment);
+ ClassDB::bind_method(D_METHOD("set_fallback_environment", "env"), &World3D::set_fallback_environment);
+ ClassDB::bind_method(D_METHOD("get_fallback_environment"), &World3D::get_fallback_environment);
+ ClassDB::bind_method(D_METHOD("set_camera_effects", "env"), &World3D::set_camera_effects);
+ ClassDB::bind_method(D_METHOD("get_camera_effects"), &World3D::get_camera_effects);
+ ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World3D::get_direct_space_state);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects");
ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
ADD_PROPERTY(PropertyInfo(Variant::_RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState", 0), "", "get_direct_space_state");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState3D", 0), "", "get_direct_space_state");
}
-World::World() {
+World3D::World3D() {
+ space = PhysicsServer3D::get_singleton()->space_create();
+ scenario = RenderingServer::get_singleton()->scenario_create();
- space = PhysicsServer::get_singleton()->space_create();
- scenario = VisualServer::get_singleton()->scenario_create();
-
- PhysicsServer::get_singleton()->space_set_active(space, true);
- PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/3d/default_gravity", 9.8));
- PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/3d/default_gravity_vector", Vector3(0, -1, 0)));
- PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/3d/default_linear_damp", 0.1));
- ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/3d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
- PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1));
- ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+ PhysicsServer3D::get_singleton()->space_set_active(space, true);
+ PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/3d/default_gravity", 9.8));
+ PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/3d/default_gravity_vector", Vector3(0, -1, 0)));
+ PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/3d/default_linear_damp", 0.1));
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+ PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1));
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
#ifdef _3D_DISABLED
- indexer = NULL;
+ indexer = nullptr;
#else
indexer = memnew(SpatialIndexer);
#endif
}
-World::~World() {
-
- PhysicsServer::get_singleton()->free(space);
- VisualServer::get_singleton()->free(scenario);
+World3D::~World3D() {
+ PhysicsServer3D::get_singleton()->free(space);
+ RenderingServer::get_singleton()->free(scenario);
#ifndef _3D_DISABLED
memdelete(indexer);
diff --git a/scene/resources/world.h b/scene/resources/world_3d.h
index b6248b28c8..02a821637f 100644
--- a/scene/resources/world.h
+++ b/scene/resources/world_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* world.h */
+/* world_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,21 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef WORLD_H
-#define WORLD_H
+#ifndef WORLD_3D_H
+#define WORLD_3D_H
#include "core/resource.h"
+#include "scene/resources/camera_effects.h"
#include "scene/resources/environment.h"
-#include "servers/physics_server.h"
-#include "servers/visual_server.h"
+#include "servers/physics_server_3d.h"
+#include "servers/rendering_server.h"
-class Camera;
-class VisibilityNotifier;
+class Camera3D;
+class VisibilityNotifier3D;
struct SpatialIndexer;
-class World : public Resource {
- GDCLASS(World, Resource);
- RES_BASE_EXTENSION("world");
+class World3D : public Resource {
+ GDCLASS(World3D, Resource);
private:
RID space;
@@ -50,20 +50,21 @@ private:
SpatialIndexer *indexer;
Ref<Environment> environment;
Ref<Environment> fallback_environment;
+ Ref<CameraEffects> camera_effects;
protected:
static void _bind_methods();
- friend class Camera;
- friend class VisibilityNotifier;
+ friend class Camera3D;
+ friend class VisibilityNotifier3D;
- void _register_camera(Camera *p_camera);
- void _update_camera(Camera *p_camera);
- void _remove_camera(Camera *p_camera);
+ void _register_camera(Camera3D *p_camera);
+ void _update_camera(Camera3D *p_camera);
+ void _remove_camera(Camera3D *p_camera);
- void _register_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect);
- void _update_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect);
- void _remove_notifier(VisibilityNotifier *p_notifier);
+ void _register_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect);
+ void _update_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect);
+ void _remove_notifier(VisibilityNotifier3D *p_notifier);
friend class Viewport;
void _update(uint64_t p_frame);
@@ -77,12 +78,15 @@ public:
void set_fallback_environment(const Ref<Environment> &p_environment);
Ref<Environment> get_fallback_environment() const;
- void get_camera_list(List<Camera *> *r_cameras);
+ void set_camera_effects(const Ref<CameraEffects> &p_camera_effects);
+ Ref<CameraEffects> get_camera_effects() const;
- PhysicsDirectSpaceState *get_direct_space_state();
+ void get_camera_list(List<Camera3D *> *r_cameras);
- World();
- ~World();
+ PhysicsDirectSpaceState3D *get_direct_space_state();
+
+ World3D();
+ ~World3D();
};
-#endif // WORLD_H
+#endif // WORLD_3D_H
diff --git a/scene/resources/plane_shape.cpp b/scene/resources/world_margin_shape_3d.cpp
index ddc820233e..0936fcc657 100644
--- a/scene/resources/plane_shape.cpp
+++ b/scene/resources/world_margin_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* plane_shape.cpp */
+/* world_margin_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,12 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "plane_shape.h"
+#include "world_margin_shape_3d.h"
-#include "servers/physics_server.h"
-
-Vector<Vector3> PlaneShape::get_debug_mesh_lines() {
+#include "servers/physics_server_3d.h"
+Vector<Vector3> WorldMarginShape3D::get_debug_mesh_lines() const {
Plane p = get_plane();
Vector<Vector3> points;
@@ -61,35 +60,30 @@ Vector<Vector3> PlaneShape::get_debug_mesh_lines() {
return points;
}
-void PlaneShape::_update_shape() {
-
- PhysicsServer::get_singleton()->shape_set_data(get_shape(), plane);
- Shape::_update_shape();
+void WorldMarginShape3D::_update_shape() {
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), plane);
+ Shape3D::_update_shape();
}
-void PlaneShape::set_plane(Plane p_plane) {
-
+void WorldMarginShape3D::set_plane(Plane p_plane) {
plane = p_plane;
_update_shape();
notify_change_to_owners();
_change_notify("plane");
}
-Plane PlaneShape::get_plane() const {
-
+Plane WorldMarginShape3D::get_plane() const {
return plane;
}
-void PlaneShape::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_plane", "plane"), &PlaneShape::set_plane);
- ClassDB::bind_method(D_METHOD("get_plane"), &PlaneShape::get_plane);
+void WorldMarginShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_plane", "plane"), &WorldMarginShape3D::set_plane);
+ ClassDB::bind_method(D_METHOD("get_plane"), &WorldMarginShape3D::get_plane);
ADD_PROPERTY(PropertyInfo(Variant::PLANE, "plane"), "set_plane", "get_plane");
}
-PlaneShape::PlaneShape() :
- Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) {
-
+WorldMarginShape3D::WorldMarginShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_PLANE)) {
set_plane(Plane(0, 1, 0, 0));
}
diff --git a/scene/resources/plane_shape.h b/scene/resources/world_margin_shape_3d.h
index 8bea1268e5..8099592d80 100644
--- a/scene/resources/plane_shape.h
+++ b/scene/resources/world_margin_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* plane_shape.h */
+/* world_margin_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,26 +28,29 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef PLANE_SHAPE_H
-#define PLANE_SHAPE_H
+#ifndef WORLD_MARGIN_SHAPE_3D_H
+#define WORLD_MARGIN_SHAPE_3D_H
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
-class PlaneShape : public Shape {
-
- GDCLASS(PlaneShape, Shape);
+class WorldMarginShape3D : public Shape3D {
+ GDCLASS(WorldMarginShape3D, Shape3D);
Plane plane;
protected:
static void _bind_methods();
- virtual void _update_shape();
+ virtual void _update_shape() override;
public:
void set_plane(Plane p_plane);
Plane get_plane() const;
- virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines() const override;
+ virtual real_t get_enclosing_radius() const override {
+ // Should be infinite?
+ return 0;
+ }
- PlaneShape();
+ WorldMarginShape3D();
};
-#endif // PLANE_SHAPE_H
+#endif // WORLD_MARGIN_SHAPE_H