summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/ConfigFile.xml1
-rw-r--r--doc/classes/EditorSceneImporterMesh.xml8
-rw-r--r--doc/classes/Mesh.xml2
-rw-r--r--editor/import/scene_importer_mesh.cpp27
-rw-r--r--editor/import/scene_importer_mesh.h7
-rw-r--r--modules/gltf/gltf_document.cpp151
-rw-r--r--scene/main/viewport.cpp234
-rw-r--r--scene/resources/mesh.cpp1
-rw-r--r--scene/resources/mesh.h1
-rw-r--r--scene/resources/surface_tool.cpp49
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp8
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp8
-rw-r--r--servers/rendering_server.cpp17
13 files changed, 337 insertions, 177 deletions
diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml
index d6da4bc248..249e2a8f80 100644
--- a/doc/classes/ConfigFile.xml
+++ b/doc/classes/ConfigFile.xml
@@ -86,6 +86,7 @@
[/codeblocks]
Keep in mind that section and property names can't contain spaces. Anything after a space will be ignored on save and on load.
ConfigFiles can also contain manually written comment lines starting with a semicolon ([code];[/code]). Those lines will be ignored when parsing the file. Note that comments will be lost when saving the ConfigFile. This can still be useful for dedicated server configuration files, which are typically never overwritten without explicit user action.
+ [b]Note:[/b] The file extension given to a ConfigFile does not have any impact on its formatting or behavior. By convention, the [code].cfg[/code] extension is used here, but any other extension such as [code].ini[/code] is also valid. Since neither [code].cfg[/code] nor [code].ini[/code] are standardized, Godot's ConfigFile formatting may differ from files written by other programs.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorSceneImporterMesh.xml b/doc/classes/EditorSceneImporterMesh.xml
index b0f233da2f..c0c53ff255 100644
--- a/doc/classes/EditorSceneImporterMesh.xml
+++ b/doc/classes/EditorSceneImporterMesh.xml
@@ -27,6 +27,7 @@
}" />
<argument index="4" name="material" type="Material" default="null" />
<argument index="5" name="name" type="String" default="&quot;&quot;" />
+ <argument index="6" name="flags" type="int" default="0" />
<description>
Creates a new surface, analogous to [method ArrayMesh.add_surface_from_arrays].
Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines, or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface.
@@ -94,6 +95,13 @@
Returns the amount of surfaces that the mesh holds.
</description>
</method>
+ <method name="get_surface_format" qualifiers="const">
+ <return type="int" />
+ <argument index="0" name="surface_idx" type="int" />
+ <description>
+ Returns the format of the surface that the mesh holds.
+ </description>
+ </method>
<method name="get_surface_lod_count" qualifiers="const">
<return type="int" />
<argument index="0" name="surface_idx" type="int" />
diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml
index bfa55c2d35..c774528a39 100644
--- a/doc/classes/Mesh.xml
+++ b/doc/classes/Mesh.xml
@@ -210,6 +210,8 @@
</constant>
<constant name="ARRAY_FORMAT_CUSTOM_BASE" value="13" enum="ArrayFormat">
</constant>
+ <constant name="ARRAY_FORMAT_CUSTOM_BITS" value="3" enum="ArrayFormat">
+ </constant>
<constant name="ARRAY_FORMAT_CUSTOM0_SHIFT" value="13" enum="ArrayFormat">
</constant>
<constant name="ARRAY_FORMAT_CUSTOM1_SHIFT" value="16" enum="ArrayFormat">
diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp
index 06f373c54f..d8248e2670 100644
--- a/editor/import/scene_importer_mesh.cpp
+++ b/editor/import/scene_importer_mesh.cpp
@@ -33,6 +33,8 @@
#include "core/math/math_defs.h"
#include "scene/resources/surface_tool.h"
+#include <cstdint>
+
void EditorSceneImporterMesh::add_blend_shape(const String &p_name) {
ERR_FAIL_COND(surfaces.size() > 0);
blend_shapes.push_back(p_name);
@@ -55,13 +57,14 @@ Mesh::BlendShapeMode EditorSceneImporterMesh::get_blend_shape_mode() const {
return blend_shape_mode;
}
-void EditorSceneImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name) {
+void EditorSceneImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name, const uint32_t p_flags) {
ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size());
ERR_FAIL_COND(p_arrays.size() != Mesh::ARRAY_MAX);
Surface s;
s.primitive = p_primitive;
s.arrays = p_arrays;
s.name = p_name;
+ s.flags = p_flags;
Vector<Vector3> vertex_array = p_arrays[Mesh::ARRAY_VERTEX];
int vertex_count = vertex_array.size();
@@ -138,6 +141,11 @@ float EditorSceneImporterMesh::get_surface_lod_size(int p_surface, int p_lod) co
return surfaces[p_surface].lods[p_lod].distance;
}
+uint32_t EditorSceneImporterMesh::get_surface_format(int p_surface) const {
+ ERR_FAIL_INDEX_V(p_surface, surfaces.size(), 0);
+ return surfaces[p_surface].flags;
+}
+
Ref<Material> EditorSceneImporterMesh::get_surface_material(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Ref<Material>());
return surfaces[p_surface].material;
@@ -283,7 +291,7 @@ Ref<ArrayMesh> EditorSceneImporterMesh::get_mesh(const Ref<ArrayMesh> &p_base) {
}
}
- mesh->add_surface_from_arrays(surfaces[i].primitive, surfaces[i].arrays, bs_data, lods);
+ mesh->add_surface_from_arrays(surfaces[i].primitive, surfaces[i].arrays, bs_data, lods, surfaces[i].flags);
if (surfaces[i].material.is_valid()) {
mesh->surface_set_material(mesh->get_surface_count() - 1, surfaces[i].material);
}
@@ -398,7 +406,7 @@ void EditorSceneImporterMesh::create_shadow_mesh() {
}
}
- shadow_mesh->add_surface(surfaces[i].primitive, new_surface, Array(), lods, Ref<Material>(), surfaces[i].name);
+ shadow_mesh->add_surface(surfaces[i].primitive, new_surface, Array(), lods, Ref<Material>(), surfaces[i].name, surfaces[i].flags);
}
}
@@ -436,7 +444,11 @@ void EditorSceneImporterMesh::_set_data(const Dictionary &p_data) {
if (s.has("material")) {
material = s["material"];
}
- add_surface(prim, arr, blend_shapes, lods, material, name);
+ uint32_t flags = 0;
+ if (s.has("flags")) {
+ flags = s["flags"];
+ }
+ add_surface(prim, arr, blend_shapes, lods, material, name, flags);
}
}
}
@@ -473,6 +485,10 @@ Dictionary EditorSceneImporterMesh::_get_data() const {
d["name"] = surfaces[i].name;
}
+ if (surfaces[i].flags != 0) {
+ d["flags"] = surfaces[i].flags;
+ }
+
surface_arr.push_back(d);
}
data["surfaces"] = surface_arr;
@@ -833,7 +849,7 @@ void EditorSceneImporterMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &EditorSceneImporterMesh::set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &EditorSceneImporterMesh::get_blend_shape_mode);
- ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name", "flags"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()), DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_surface_count"), &EditorSceneImporterMesh::get_surface_count);
ClassDB::bind_method(D_METHOD("get_surface_primitive_type", "surface_idx"), &EditorSceneImporterMesh::get_surface_primitive_type);
@@ -844,6 +860,7 @@ void EditorSceneImporterMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_surface_lod_size", "surface_idx", "lod_idx"), &EditorSceneImporterMesh::get_surface_lod_size);
ClassDB::bind_method(D_METHOD("get_surface_lod_indices", "surface_idx", "lod_idx"), &EditorSceneImporterMesh::get_surface_lod_indices);
ClassDB::bind_method(D_METHOD("get_surface_material", "surface_idx"), &EditorSceneImporterMesh::get_surface_material);
+ ClassDB::bind_method(D_METHOD("get_surface_format", "surface_idx"), &EditorSceneImporterMesh::get_surface_format);
ClassDB::bind_method(D_METHOD("set_surface_name", "surface_idx", "name"), &EditorSceneImporterMesh::set_surface_name);
ClassDB::bind_method(D_METHOD("set_surface_material", "surface_idx", "material"), &EditorSceneImporterMesh::set_surface_material);
diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h
index e57e479d8e..c8e25244fa 100644
--- a/editor/import/scene_importer_mesh.h
+++ b/editor/import/scene_importer_mesh.h
@@ -36,6 +36,9 @@
#include "scene/resources/convex_polygon_shape_3d.h"
#include "scene/resources/mesh.h"
#include "scene/resources/navigation_mesh.h"
+
+#include <cstdint>
+
// The following classes are used by importers instead of ArrayMesh and MeshInstance3D
// so the data is not registered (hence, quality loss), importing happens faster and
// its easier to modify before saving
@@ -57,6 +60,7 @@ class EditorSceneImporterMesh : public Resource {
Vector<LOD> lods;
Ref<Material> material;
String name;
+ uint32_t flags = 0;
};
Vector<Surface> surfaces;
Vector<String> blend_shapes;
@@ -80,7 +84,7 @@ public:
int get_blend_shape_count() const;
String get_blend_shape_name(int p_blend_shape) const;
- void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String());
+ void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String(), const uint32_t p_flags = 0);
int get_surface_count() const;
void set_blend_shape_mode(Mesh::BlendShapeMode p_blend_shape_mode);
@@ -95,6 +99,7 @@ public:
Vector<int> get_surface_lod_indices(int p_surface, int p_lod) const;
float get_surface_lod_size(int p_surface, int p_lod) const;
Ref<Material> get_surface_material(int p_surface) const;
+ uint32_t get_surface_format(int p_surface) const;
void set_surface_material(int p_surface, const Ref<Material> &p_material);
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index d307bda85c..db324e23b7 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -48,6 +48,7 @@
#include "core/io/file_access.h"
#include "core/io/json.h"
#include "core/math/disjoint_set.h"
+#include "core/math/vector2.h"
#include "core/variant/typed_array.h"
#include "core/variant/variant.h"
#include "core/version.h"
@@ -61,7 +62,7 @@
#include "scene/resources/surface_tool.h"
#include "modules/modules_enabled.gen.h"
-#include <cstdint>
+
#ifdef MODULE_CSG_ENABLED
#include "modules/csg/csg_shape.h"
#endif // MODULE_CSG_ENABLED
@@ -71,6 +72,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <cstdint>
#include <limits>
Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &p_path) {
@@ -2171,11 +2173,14 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
}
Array array = import_mesh->get_surface_arrays(surface_i);
+ uint32_t format = import_mesh->get_surface_format(surface_i);
+ int32_t vertex_num = 0;
Dictionary attributes;
{
Vector<Vector3> a = array[Mesh::ARRAY_VERTEX];
ERR_FAIL_COND_V(!a.size(), ERR_INVALID_DATA);
attributes["POSITION"] = _encode_accessor_as_vec3(state, a, true);
+ vertex_num = a.size();
}
{
Vector<real_t> a = array[Mesh::ARRAY_TANGENT];
@@ -2218,6 +2223,58 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
attributes["TEXCOORD_1"] = _encode_accessor_as_vec2(state, a, true);
}
}
+ for (int custom_i = 0; custom_i < 3; custom_i++) {
+ Vector<float> a = array[Mesh::ARRAY_CUSTOM0 + custom_i];
+ if (a.size()) {
+ int num_channels = 4;
+ int custom_shift = Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT + custom_i * Mesh::ARRAY_FORMAT_CUSTOM_BITS;
+ switch ((format >> custom_shift) & Mesh::ARRAY_FORMAT_CUSTOM_MASK) {
+ case Mesh::ARRAY_CUSTOM_R_FLOAT:
+ num_channels = 1;
+ break;
+ case Mesh::ARRAY_CUSTOM_RG_FLOAT:
+ num_channels = 2;
+ break;
+ case Mesh::ARRAY_CUSTOM_RGB_FLOAT:
+ num_channels = 3;
+ break;
+ case Mesh::ARRAY_CUSTOM_RGBA_FLOAT:
+ num_channels = 4;
+ break;
+ }
+ int texcoord_i = 2 + 2 * custom_i;
+ String gltf_texcoord_key;
+ for (int prev_texcoord_i = 0; prev_texcoord_i < texcoord_i; prev_texcoord_i++) {
+ gltf_texcoord_key = vformat("TEXCOORD_%d", prev_texcoord_i);
+ if (!attributes.has(gltf_texcoord_key)) {
+ Vector<Vector2> empty;
+ empty.resize(vertex_num);
+ attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(state, empty, true);
+ }
+ }
+
+ LocalVector<Vector2> first_channel;
+ first_channel.resize(vertex_num);
+ LocalVector<Vector2> second_channel;
+ second_channel.resize(vertex_num);
+ for (int32_t vert_i = 0; vert_i < vertex_num; vert_i++) {
+ float u = a[vert_i * num_channels + 0];
+ float v = (num_channels == 1 ? 0.0f : a[vert_i * num_channels + 1]);
+ first_channel[vert_i] = Vector2(u, v);
+ u = 0;
+ v = 0;
+ if (num_channels >= 3) {
+ u = a[vert_i * num_channels + 2];
+ v = (num_channels == 3 ? 0.0f : a[vert_i * num_channels + 3]);
+ second_channel[vert_i] = Vector2(u, v);
+ }
+ }
+ gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i);
+ attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(state, first_channel, true);
+ gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i + 1);
+ attributes[gltf_texcoord_key] = _encode_accessor_as_vec2(state, second_channel, true);
+ }
+ }
{
Vector<Color> a = array[Mesh::ARRAY_COLOR];
if (a.size()) {
@@ -2253,13 +2310,12 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
}
attributes["JOINTS_0"] = _encode_accessor_as_joints(state, attribs, true);
} else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
- int32_t vertex_count = vertex_array.size();
Vector<Color> joints_0;
- joints_0.resize(vertex_count);
+ joints_0.resize(vertex_num);
Vector<Color> joints_1;
- joints_1.resize(vertex_count);
+ joints_1.resize(vertex_num);
int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
- for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
Color joint_0;
joint_0.r = a[vertex_i * weights_8_count + 0];
joint_0.g = a[vertex_i * weights_8_count + 1];
@@ -2289,13 +2345,12 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
}
attributes["WEIGHTS_0"] = _encode_accessor_as_weights(state, attribs, true);
} else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
- int32_t vertex_count = vertex_array.size();
Vector<Color> weights_0;
- weights_0.resize(vertex_count);
+ weights_0.resize(vertex_num);
Vector<Color> weights_1;
- weights_1.resize(vertex_count);
+ weights_1.resize(vertex_num);
int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
- for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
Color weight_0;
weight_0.r = a[vertex_i * weights_8_count + 0];
weight_0.g = a[vertex_i * weights_8_count + 1];
@@ -2459,7 +2514,8 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
ERR_FAIL_COND_V(!d.has("primitives"), ERR_PARSE_ERROR);
Array primitives = d["primitives"];
- const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary();
+ const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] :
+ Dictionary();
Ref<EditorSceneImporterMesh> import_mesh;
import_mesh.instantiate();
String mesh_name = "mesh";
@@ -2469,6 +2525,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
import_mesh->set_name(_gen_unique_name(state, vformat("%s_%s", state->scene_name, mesh_name)));
for (int j = 0; j < primitives.size(); j++) {
+ uint32_t flags = 0;
Dictionary p = primitives[j];
Array array;
@@ -2500,8 +2557,11 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
}
ERR_FAIL_COND_V(!a.has("POSITION"), ERR_PARSE_ERROR);
+ int32_t vertex_num = 0;
if (a.has("POSITION")) {
- array[Mesh::ARRAY_VERTEX] = _decode_accessor_as_vec3(state, a["POSITION"], true);
+ PackedVector3Array vertices = _decode_accessor_as_vec3(state, a["POSITION"], true);
+ array[Mesh::ARRAY_VERTEX] = vertices;
+ vertex_num = vertices.size();
}
if (a.has("NORMAL")) {
array[Mesh::ARRAY_NORMAL] = _decode_accessor_as_vec3(state, a["NORMAL"], true);
@@ -2515,6 +2575,60 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
if (a.has("TEXCOORD_1")) {
array[Mesh::ARRAY_TEX_UV2] = _decode_accessor_as_vec2(state, a["TEXCOORD_1"], true);
}
+ for (int custom_i = 0; custom_i < 3; custom_i++) {
+ Vector<float> cur_custom;
+ Vector<Vector2> texcoord_first;
+ Vector<Vector2> texcoord_second;
+
+ int texcoord_i = 2 + 2 * custom_i;
+ String gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i);
+ int num_channels = 0;
+ if (a.has(gltf_texcoord_key)) {
+ texcoord_first = _decode_accessor_as_vec2(state, a[gltf_texcoord_key], true);
+ num_channels = 2;
+ }
+ gltf_texcoord_key = vformat("TEXCOORD_%d", texcoord_i + 1);
+ if (a.has(gltf_texcoord_key)) {
+ texcoord_second = _decode_accessor_as_vec2(state, a[gltf_texcoord_key], true);
+ num_channels = 4;
+ }
+ if (!num_channels) {
+ break;
+ }
+ if (num_channels == 2 || num_channels == 4) {
+ cur_custom.resize(vertex_num * num_channels);
+ for (int32_t uv_i = 0; uv_i < texcoord_first.size() && uv_i < vertex_num; uv_i++) {
+ cur_custom.write[uv_i * num_channels + 0] = texcoord_first[uv_i].x;
+ cur_custom.write[uv_i * num_channels + 1] = texcoord_first[uv_i].y;
+ }
+ // Vector.resize seems to not zero-initialize. Ensure all unused elements are 0:
+ for (int32_t uv_i = texcoord_first.size(); uv_i < vertex_num; uv_i++) {
+ cur_custom.write[uv_i * num_channels + 0] = 0;
+ cur_custom.write[uv_i * num_channels + 1] = 0;
+ }
+ }
+ if (num_channels == 4) {
+ for (int32_t uv_i = 0; uv_i < texcoord_second.size() && uv_i < vertex_num; uv_i++) {
+ // num_channels must be 4
+ cur_custom.write[uv_i * num_channels + 2] = texcoord_second[uv_i].x;
+ cur_custom.write[uv_i * num_channels + 3] = texcoord_second[uv_i].y;
+ }
+ // Vector.resize seems to not zero-initialize. Ensure all unused elements are 0:
+ for (int32_t uv_i = texcoord_second.size(); uv_i < vertex_num; uv_i++) {
+ cur_custom.write[uv_i * num_channels + 2] = 0;
+ cur_custom.write[uv_i * num_channels + 3] = 0;
+ }
+ }
+ if (cur_custom.size() > 0) {
+ array[Mesh::ARRAY_CUSTOM0 + custom_i] = cur_custom;
+ int custom_shift = Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT + custom_i * Mesh::ARRAY_FORMAT_CUSTOM_BITS;
+ if (num_channels == 2) {
+ flags |= Mesh::ARRAY_CUSTOM_RG_FLOAT << custom_shift;
+ } else {
+ flags |= Mesh::ARRAY_CUSTOM_RGBA_FLOAT << custom_shift;
+ }
+ }
+ }
if (a.has("COLOR_0")) {
array[Mesh::ARRAY_COLOR] = _decode_accessor_as_color(state, a["COLOR_0"], true);
has_vertex_color = true;
@@ -2526,10 +2640,9 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
PackedInt32Array joints_1 = _decode_accessor_as_ints(state, a["JOINTS_1"], true);
ERR_FAIL_COND_V(joints_0.size() != joints_0.size(), ERR_INVALID_DATA);
int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
- int32_t vertex_count = joints_0.size() / JOINT_GROUP_SIZE;
Vector<int> joints;
- joints.resize(vertex_count * weight_8_count);
- for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ joints.resize(vertex_num * weight_8_count);
+ for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
joints.write[vertex_i * weight_8_count + 0] = joints_0[vertex_i * JOINT_GROUP_SIZE + 0];
joints.write[vertex_i * weight_8_count + 1] = joints_0[vertex_i * JOINT_GROUP_SIZE + 1];
joints.write[vertex_i * weight_8_count + 2] = joints_0[vertex_i * JOINT_GROUP_SIZE + 2];
@@ -2568,9 +2681,8 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
Vector<float> weights;
ERR_FAIL_COND_V(weights_0.size() != weights_1.size(), ERR_INVALID_DATA);
int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
- int32_t vertex_count = weights_0.size() / JOINT_GROUP_SIZE;
- weights.resize(vertex_count * weight_8_count);
- for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ weights.resize(vertex_num * weight_8_count);
+ for (int32_t vertex_i = 0; vertex_i < vertex_num; vertex_i++) {
weights.write[vertex_i * weight_8_count + 0] = weights_0[vertex_i * JOINT_GROUP_SIZE + 0];
weights.write[vertex_i * weight_8_count + 1] = weights_0[vertex_i * JOINT_GROUP_SIZE + 1];
weights.write[vertex_i * weight_8_count + 2] = weights_0[vertex_i * JOINT_GROUP_SIZE + 2];
@@ -2798,7 +2910,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
mat = mat3d;
}
- import_mesh->add_surface(primitive, array, morphs, Dictionary(), mat, mat.is_valid() ? mat->get_name() : String());
+ import_mesh->add_surface(primitive, array, morphs, Dictionary(), mat, mat.is_valid() ? mat->get_name() : String(), flags);
}
Vector<float> blend_weights;
@@ -2954,6 +3066,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat
}
}
} else { // Relative path to an external image file.
+ uri = uri.uri_decode();
uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows.
// ResourceLoader will rely on the file extension to use the relevant loader.
// The spec says that if mimeType is defined, it should take precedence (e.g.
@@ -4897,7 +5010,7 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_instance(Ref<GLTFState> state, MeshIns
if (p_mesh_instance->get_material_override().is_valid()) {
mat = p_mesh_instance->get_material_override();
}
- import_mesh->add_surface(primitive_type, arrays, blend_shape_arrays, Dictionary(), mat, surface_name);
+ import_mesh->add_surface(primitive_type, arrays, blend_shape_arrays, Dictionary(), mat, surface_name, godot_mesh->surface_get_format(surface_i));
}
for (int32_t blend_i = 0; blend_i < blend_count; blend_i++) {
blend_weights.write[blend_i] = 0.0f;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index cca53c63bf..a352953c4b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -81,7 +81,7 @@ void ViewportTexture::setup_local_to_scene() {
RS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid);
RS::get_singleton()->free(proxy_ph);
} else {
- ERR_FAIL_COND(proxy.is_valid()); //should be invalid
+ ERR_FAIL_COND(proxy.is_valid()); // Should be invalid.
proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid);
}
}
@@ -118,7 +118,6 @@ Size2 ViewportTexture::get_size() const {
}
RID ViewportTexture::get_rid() const {
- //ERR_FAIL_COND_V_MSG(!vp, RID(), "Viewport Texture must be set to use it.");
if (proxy.is_null()) {
proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
@@ -263,7 +262,7 @@ void Viewport::_sub_window_update(Window *p_window) {
void Viewport::_sub_window_grab_focus(Window *p_window) {
if (p_window == nullptr) {
- //release current focus
+ // Release current focus.
if (gui.subwindow_focused) {
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
gui.subwindow_focused = nullptr;
@@ -289,18 +288,18 @@ void Viewport::_sub_window_grab_focus(Window *p_window) {
ERR_FAIL_COND(index == -1);
if (p_window->get_flag(Window::FLAG_NO_FOCUS)) {
- //can only move to foreground, but no focus granted
+ // Can only move to foreground, but no focus granted.
SubWindow sw = gui.sub_windows[index];
gui.sub_windows.remove(index);
gui.sub_windows.push_back(sw);
index = gui.sub_windows.size() - 1;
_sub_window_update_order();
- return; //i guess not...
+ return;
}
if (gui.subwindow_focused) {
if (gui.subwindow_focused == p_window) {
- return; //nothing to do
+ return; // Nothing to do.
}
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
@@ -317,7 +316,7 @@ void Viewport::_sub_window_grab_focus(Window *p_window) {
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_IN);
- { //move to foreground
+ { // Move to foreground.
SubWindow sw = gui.sub_windows[index];
gui.sub_windows.remove(index);
gui.sub_windows.push_back(sw);
@@ -423,7 +422,7 @@ void Viewport::_notification(int p_what) {
}
if (camera_3d_set.size() && !camera_3d) {
- //there are cameras but no current camera, pick first in tree and make it current
+ // There are cameras but no current camera, pick first in tree and make it current.
Camera3D *first = nullptr;
for (Set<Camera3D *>::Element *E = camera_3d_set.front(); E; E = E->next()) {
if (first == nullptr || first->is_greater_than(E->get())) {
@@ -522,8 +521,9 @@ void Viewport::_process_picking() {
PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
if (physics_has_last_mousepos) {
- // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved.
- // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame
+ // If no mouse event exists, create a motion one. This is necessary because objects or camera may have moved.
+ // While this extra event is sent, it is checked if both camera and last object and last ID did not move.
+ // If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame.
bool has_mouse_event = false;
for (const Ref<InputEvent> &m : physics_picking_events) {
if (m.is_valid()) {
@@ -597,7 +597,7 @@ void Viewport::_process_picking() {
Ref<InputEventKey> k = ev;
if (k.is_valid()) {
- //only for mask
+ // Only for mask.
physics_last_mouse_state.alt = k->is_alt_pressed();
physics_last_mouse_state.shift = k->is_shift_pressed();
physics_last_mouse_state.control = k->is_ctrl_pressed();
@@ -618,7 +618,7 @@ void Viewport::_process_picking() {
}
if (ss2d) {
- //send to 2D
+ // Send to 2D.
uint64_t frame = get_tree()->get_frame();
@@ -627,11 +627,11 @@ void Viewport::_process_picking() {
Transform2D canvas_transform;
ObjectID canvas_layer_id;
if (E->get()) {
- // A descendant CanvasLayer
+ // A descendant CanvasLayer.
canvas_transform = E->get()->get_transform();
canvas_layer_id = E->get()->get_instance_id();
} else {
- // This Viewport's builtin canvas
+ // This Viewport's builtin canvas.
canvas_transform = get_canvas_transform();
canvas_layer_id = ObjectID();
}
@@ -651,7 +651,7 @@ void Viewport::_process_picking() {
co->_mouse_enter();
} else {
F->get() = frame;
- // It was already hovered, so don't send the event if it's faked
+ // It was already hovered, so don't send the event if it's faked.
if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
send_event = false;
}
@@ -700,11 +700,11 @@ void Viewport::_process_picking() {
}
if (captured) {
- //none
+ // None.
} else if (pos == last_pos) {
if (last_id.is_valid()) {
if (ObjectDB::get_instance(last_id) && last_object) {
- //good, exists
+ // Good, exists.
_collision_object_3d_input_event(last_object, camera_3d, ev, result.position, result.normal, result.shape);
if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
physics_object_capture = last_id;
@@ -1121,7 +1121,7 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont
while (p_control) {
tooltip = p_control->get_tooltip(pos);
- //Temporary solution for PopupMenus
+ // Temporary solution for PopupMenus.
PopupMenu *menu = Object::cast_to<PopupMenu>(this);
if (menu) {
tooltip = menu->get_tooltip(pos);
@@ -1235,11 +1235,9 @@ void Viewport::_gui_show_tooltip() {
}
void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_input) {
- //_block();
-
Ref<InputEvent> ev = p_input;
- //mouse wheel events can't be stopped
+ // Mouse wheel events can't be stopped.
Ref<InputEventMouseButton> mb = p_input;
bool cant_stop_me_now = (mb.is_valid() &&
@@ -1275,11 +1273,9 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
break;
}
- ev = ev->xformed_by(ci->get_transform()); //transform event upwards
+ ev = ev->xformed_by(ci->get_transform()); // Transform event upwards.
ci = ci->get_parent_item();
}
-
- //_unblock();
}
void Viewport::_gui_call_notification(Control *p_control, int p_what) {
@@ -1309,12 +1305,10 @@ void Viewport::_gui_call_notification(Control *p_control, int p_what) {
ci = ci->get_parent_item();
}
-
- //_unblock();
}
Control *Viewport::gui_find_control(const Point2 &p_global) {
- //aca va subwindows
+ // Handle subwindows.
_gui_sort_roots();
for (List<Control *>::Element *E = gui.roots.back(); E; E = E->prev()) {
@@ -1346,8 +1340,7 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_
}
if (!p_node->is_visible()) {
- //return _find_next_visible_control_at_pos(p_node,p_global,r_inv_xform);
- return nullptr; //canvas item hidden, discard
+ return nullptr; // Canvas item hidden, discard.
}
Transform2D matrix = p_xform * p_node->get_transform();
@@ -1391,32 +1384,31 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_
}
bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check) {
- { //attempt grab, try parent controls too
- CanvasItem *ci = p_at_control;
- while (ci) {
- Control *control = Object::cast_to<Control>(ci);
- if (control) {
- if (control->can_drop_data(p_at_pos, gui.drag_data)) {
- if (!p_just_check) {
- control->drop_data(p_at_pos, gui.drag_data);
- }
-
- return true;
+ // Attempt grab, try parent controls too.
+ CanvasItem *ci = p_at_control;
+ while (ci) {
+ Control *control = Object::cast_to<Control>(ci);
+ if (control) {
+ if (control->can_drop_data(p_at_pos, gui.drag_data)) {
+ if (!p_just_check) {
+ control->drop_data(p_at_pos, gui.drag_data);
}
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
- break;
- }
+ return true;
}
- p_at_pos = ci->get_transform().xform(p_at_pos);
-
- if (ci->is_set_as_top_level()) {
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
}
+ }
+
+ p_at_pos = ci->get_transform().xform(p_at_pos);
- ci = ci->get_parent_item();
+ if (ci->is_set_as_top_level()) {
+ break;
}
+
+ ci = ci->get_parent_item();
}
return false;
@@ -1436,16 +1428,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (mb->is_pressed()) {
Size2 pos = mpos;
if (gui.mouse_focus_mask) {
- //do not steal mouse focus and stuff while a focus mask exists
- gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); //add the button to the mask
+ // Do not steal mouse focus and stuff while a focus mask exists.
+ gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); // Add the button to the mask.
} else {
- //Matrix32 parent_xform;
-
- /*
- if (data.parent_canvas_item)
- parent_xform=data.parent_canvas_item->get_global_transform();
- */
-
gui.mouse_focus = gui_find_control(pos);
gui.last_mouse_focus = gui.mouse_focus;
@@ -1462,7 +1447,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- mb = mb->xformed_by(Transform2D()); // make a copy of the event
+ mb = mb->xformed_by(Transform2D()); // Make a copy of the event.
mb->set_global_position(pos);
@@ -1479,7 +1464,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
#endif
- if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { //assign focus
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { // Assign focus.
CanvasItem *ci = gui.mouse_focus;
while (ci) {
Control *control = Object::cast_to<Control>(ci);
@@ -1511,7 +1496,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
set_input_as_handled();
if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
- //alternate drop use (when using force_drag(), as proposed by #5342
+ // Alternate drop use (when using force_drag(), as proposed by #5342).
if (gui.mouse_focus) {
_gui_drop(gui.mouse_focus, pos, false);
}
@@ -1525,7 +1510,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_preview_id = ObjectID();
}
_propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- //change mouse accordingly
+ // Change mouse accordingly.
}
_gui_cancel_tooltip();
@@ -1545,26 +1530,28 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.dragging = false;
gui.drag_mouse_over = nullptr;
_propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- //change mouse accordingly
+ // Change mouse accordingly.
}
- gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); //remove from mask
+ gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); // Remove from mask.
if (!gui.mouse_focus) {
- //release event is only sent if a mouse focus (previously pressed button) exists
+ // Release event is only sent if a mouse focus (previously pressed button) exists.
return;
}
Size2 pos = mpos;
- mb = mb->xformed_by(Transform2D()); //make a copy
+ mb = mb->xformed_by(Transform2D()); // Make a copy.
mb->set_global_position(pos);
pos = gui.focus_inv_xform.xform(pos);
mb->set_position(pos);
Control *mouse_focus = gui.mouse_focus;
- //disable mouse focus if needed before calling input, this makes popups on mouse press event work better, as the release will never be received otherwise
+ // Disable mouse focus if needed before calling input,
+ // this makes popups on mouse press event work better,
+ // as the release will never be received otherwise.
if (gui.mouse_focus_mask == 0) {
gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false;
@@ -1574,11 +1561,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_gui_call_input(mouse_focus, mb);
}
- /*if (gui.drag_data.get_type()!=Variant::NIL && mb->get_button_index()==MOUSE_BUTTON_LEFT) {
- _propagate_viewport_notification(this,NOTIFICATION_DRAG_END);
- gui.drag_data=Variant(); //always clear
- }*/
-
// In case the mouse was released after for example dragging a scrollbar,
// check whether the current control is different from the stored one. If
// it is different, rather than wait for it to be updated the next time the
@@ -1617,12 +1599,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = nullptr;
- // D&D
+ // Drag & drop.
if (!gui.drag_attempted && gui.mouse_focus && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
gui.drag_accum += mm->get_relative();
float len = gui.drag_accum.length();
if (len > 10) {
- { //attempt grab, try parent controls too
+ { // Attempt grab, try parent controls too.
CanvasItem *ci = gui.mouse_focus;
while (ci) {
Control *control = Object::cast_to<Control>(ci);
@@ -1695,14 +1677,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Vector2 speed = localizer.basis_xform(mm->get_speed());
Vector2 rel = localizer.basis_xform(mm->get_relative());
- mm = mm->xformed_by(Transform2D()); //make a copy
+ mm = mm->xformed_by(Transform2D()); // Make a copy.
mm->set_global_position(mpos);
mm->set_speed(speed);
mm->set_relative(rel);
if (mm->get_button_mask() == 0) {
- //nothing pressed
+ // Nothing pressed.
bool can_tooltip = true;
@@ -1726,7 +1708,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
is_tooltip_shown = true;
}
} else {
- is_tooltip_shown = true; //well, nothing to compare against, likely using custom control, so if it changes there is nothing we can do
+ is_tooltip_shown = true; // Nothing to compare against, likely using custom control, so if it changes there is nothing we can do.
}
}
} else {
@@ -1783,7 +1765,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (gui.drag_data.get_type() != Variant::NIL) {
- //handle dragandrop
+ // Handle drag & drop.
Control *drag_preview = _gui_get_drag_preview();
if (drag_preview) {
@@ -1793,9 +1775,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_mouse_over = over;
gui.drag_mouse_over_pos = Vector2();
- //find the window this is above of
-
- //see if there is an embedder
+ // Find the window this is above of.
+ // See if there is an embedder.
Viewport *embedder = nullptr;
Vector2 viewport_pos;
@@ -1803,7 +1784,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
embedder = this;
viewport_pos = mpos;
} else {
- //not an embedder, but may be a subwindow of an embedder
+ // Not an embedder, but may be a subwindow of an embedder.
Window *w = Object::cast_to<Window>(this);
if (w) {
if (w->is_embedded()) {
@@ -1811,7 +1792,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Transform2D ai = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse();
- viewport_pos = ai.xform(mpos) + w->get_position(); //to parent coords
+ viewport_pos = ai.xform(mpos) + w->get_position(); // To parent coords.
}
}
}
@@ -1819,7 +1800,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Viewport *viewport_under = nullptr;
if (embedder) {
- //use embedder logic
+ // Use embedder logic.
for (int i = embedder->gui.sub_windows.size() - 1; i >= 0; i--) {
Window *sw = embedder->gui.sub_windows[i].window;
@@ -1837,11 +1818,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (!viewport_under) {
- //not in a subwindow, likely in embedder
+ // Not in a subwindow, likely in embedder.
viewport_under = embedder;
}
} else {
- //use displayserver logic
+ // Use DisplayServer logic.
Vector2i screen_mouse_pos = DisplayServer::get_singleton()->mouse_get_position();
DisplayServer::WindowID window_id = DisplayServer::get_singleton()->get_window_at_screen_position(screen_mouse_pos);
@@ -1849,7 +1830,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
ObjectID object_under = DisplayServer::get_singleton()->window_get_attached_instance_id(window_id);
- if (object_under != ObjectID()) { //fetch window
+ if (object_under != ObjectID()) { // Fetch window.
Window *w = Object::cast_to<Window>(ObjectDB::get_instance(object_under));
if (w) {
viewport_under = w;
@@ -1862,7 +1843,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (viewport_under) {
Transform2D ai = (viewport_under->get_final_transform().affine_inverse() * viewport_under->_get_input_pre_xform());
viewport_pos = ai.xform(viewport_pos);
- //find control under at pos
+ // Find control under at position.
gui.drag_mouse_over = viewport_under->gui_find_control(viewport_pos);
if (gui.drag_mouse_over) {
Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse();
@@ -1894,7 +1875,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = gui_find_control(pos);
if (over) {
if (over->can_process()) {
- touch_event = touch_event->xformed_by(Transform2D()); //make a copy
+ touch_event = touch_event->xformed_by(Transform2D()); // Make a copy.
if (over == gui.mouse_focus) {
pos = gui.focus_inv_xform.xform(pos);
} else {
@@ -1908,7 +1889,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
} else if (touch_event->get_index() == 0 && gui.last_mouse_focus) {
if (gui.last_mouse_focus->can_process()) {
- touch_event = touch_event->xformed_by(Transform2D()); //make a copy
+ touch_event = touch_event->xformed_by(Transform2D()); // Make a copy.
touch_event->set_position(gui.focus_inv_xform.xform(pos));
_gui_call_input(gui.last_mouse_focus, touch_event);
@@ -1929,7 +1910,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = gui_find_control(pos);
if (over) {
if (over->can_process()) {
- gesture_event = gesture_event->xformed_by(Transform2D()); //make a copy
+ gesture_event = gesture_event->xformed_by(Transform2D()); // Make a copy.
if (over == gui.mouse_focus) {
pos = gui.focus_inv_xform.xform(pos);
} else {
@@ -1956,7 +1937,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Vector2 speed = localizer.basis_xform(drag_event->get_speed());
Vector2 rel = localizer.basis_xform(drag_event->get_relative());
- drag_event = drag_event->xformed_by(Transform2D()); //make a copy
+ drag_event = drag_event->xformed_by(Transform2D()); // Make a copy.
drag_event->set_speed(speed);
drag_event->set_relative(rel);
@@ -1987,12 +1968,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- Control *from = gui.key_focus ? gui.key_focus : nullptr; //hmm
+ Control *from = gui.key_focus ? gui.key_focus : nullptr;
- //keyboard focus
- //if (from && p_event->is_pressed() && !p_event->is_alt_pressed() && !p_event->is_meta_pressed() && !p_event->key->is_command_pressed()) {
+ // Keyboard focus.
Ref<InputEventKey> k = p_event;
- //need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/right/etc> is handled here when it shouldn't be.
+ // Need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/right/etc> is handled here when it shouldn't be.
bool mods = k.is_valid() && (k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_shift_pressed() || k->is_meta_pressed());
if (from && p_event->is_pressed()) {
@@ -2063,7 +2043,7 @@ void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
}
p_control->set_as_top_level(true);
p_control->set_position(gui.last_mouse_pos);
- p_base->get_root_parent_control()->add_child(p_control); //add as child of viewport
+ p_base->get_root_parent_control()->add_child(p_control); // Add as child of viewport.
p_control->raise();
gui.drag_preview_id = p_control->get_instance_id();
@@ -2165,8 +2145,8 @@ bool Viewport::_gui_control_has_focus(const Control *p_control) {
}
void Viewport::_gui_control_grab_focus(Control *p_control) {
- //no need for change
if (gui.key_focus && gui.key_focus == p_control) {
+ // No need for change.
return;
}
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "_viewports", "_gui_remove_focus_for_window", (Node *)get_base_window());
@@ -2248,7 +2228,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
to_erase.pop_front();
}
- // Per-shape
+ // Per-shape.
List<Map<Pair<ObjectID, int>, uint64_t, PairSort<ObjectID, int>>::Element *> shapes_to_erase;
for (Map<Pair<ObjectID, int>, uint64_t, PairSort<ObjectID, int>>::Element *E = physics_2d_shape_mouseover.front(); E; E = E->next()) {
@@ -2287,7 +2267,7 @@ void Viewport::_gui_grab_click_focus(Control *p_control) {
void Viewport::_post_gui_grab_click_focus() {
Control *focus_grabber = gui.mouse_click_grabber;
if (!focus_grabber) {
- // Redundant grab requests were made
+ // Redundant grab requests were made.
return;
}
gui.mouse_click_grabber = nullptr;
@@ -2305,7 +2285,7 @@ void Viewport::_post_gui_grab_click_focus() {
Ref<InputEventMouseButton> mb;
mb.instantiate();
- //send unclick
+ // Send unclick.
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
@@ -2323,7 +2303,7 @@ void Viewport::_post_gui_grab_click_focus() {
Ref<InputEventMouseButton> mb;
mb.instantiate();
- //send click
+ // Send click.
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
@@ -2360,7 +2340,7 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw
r.size.y += title_height;
if (r.has_point(p_point)) {
- return SUB_WINDOW_RESIZE_DISABLED; //it's inside, so no resize
+ return SUB_WINDOW_RESIZE_DISABLED; // It's inside, so no resize.
}
int dist_x = p_point.x < r.position.x ? (p_point.x - r.position.x) : (p_point.x > (r.position.x + r.size.x) ? (p_point.x - (r.position.x + r.size.x)) : 0);
@@ -2419,12 +2399,12 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) {
if (gui.subwindow_drag_close_rect.has_point(mb->get_position())) {
- //close window
+ // Close window.
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST);
}
}
gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
- if (gui.subwindow_focused != nullptr) { //may have been erased
+ if (gui.subwindow_focused != nullptr) { // May have been erased.
_sub_window_update(gui.subwindow_focused);
}
}
@@ -2531,27 +2511,27 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
gui.subwindow_focused->_rect_changed_callback(r);
}
- if (gui.subwindow_focused) { //may have been erased
+ if (gui.subwindow_focused) { // May have been erased.
_sub_window_update(gui.subwindow_focused);
}
}
- return true; //handled
+ return true; // Handled.
}
Ref<InputEventMouseButton> mb = p_event;
- //if the event is a mouse button, we need to check whether another window was clicked
+ // If the event is a mouse button, we need to check whether another window was clicked.
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
bool click_on_window = false;
for (int i = gui.sub_windows.size() - 1; i >= 0; i--) {
SubWindow &sw = gui.sub_windows.write[i];
- //clicked inside window?
+ // Clicked inside window?
Rect2i r = Rect2i(sw.window->get_position(), sw.window->get_size());
if (!sw.window->get_flag(Window::FLAG_BORDERLESS)) {
- //check top bar
+ // Check top bar.
int title_height = sw.window->get_theme_constant(SNAME("title_height"));
Rect2i title_bar = r;
title_bar.position.y -= title_height;
@@ -2569,13 +2549,13 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
close_rect.size = close_icon->get_size();
if (gui.subwindow_focused != sw.window) {
- //refocus
+ // Refocus.
_sub_window_grab_focus(sw.window);
}
if (close_rect.has_point(mb->get_position())) {
gui.subwindow_drag = SUB_WINDOW_DRAG_CLOSE;
- gui.subwindow_drag_close_inside = true; //starts inside
+ gui.subwindow_drag_close_inside = true; // Starts inside.
gui.subwindow_drag_close_rect = close_rect;
} else {
gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE;
@@ -2596,9 +2576,9 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
}
if (!click_on_window && r.has_point(mb->get_position())) {
- //clicked, see if it needs to fetch focus
+ // Clicked, see if it needs to fetch focus.
if (gui.subwindow_focused != sw.window) {
- //refocus
+ // Refocus.
_sub_window_grab_focus(sw.window);
}
@@ -2611,7 +2591,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
if (!click_on_window && gui.subwindow_focused) {
- //no window found and clicked, remove focus
+ // No window found and clicked, remove focus.
_sub_window_grab_focus(nullptr);
}
}
@@ -2635,13 +2615,13 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
DisplayServer::get_singleton()->cursor_set_shape(shapes[resize]);
- return true; //reserved for showing the resize cursor
+ return true; // Reserved for showing the resize cursor.
}
}
}
if (gui.subwindow_drag != SUB_WINDOW_DRAG_DISABLED) {
- return true; // dragging, don't pass the event
+ return true; // Dragging, don't pass the event.
}
if (!gui.subwindow_focused) {
@@ -2718,10 +2698,10 @@ void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local
ev = p_event;
}
- // Unhandled Input
+ // Unhandled Input.
get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, ev, this);
- // Unhandled key Input - used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, etc
+ // Unhandled key Input - used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, etc.
if (!is_input_handled() && (Object::cast_to<InputEventKey>(*ev) != nullptr || Object::cast_to<InputEventShortcut>(*ev) != nullptr)) {
get_tree()->_call_input_pause(unhandled_key_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, ev, this);
}
@@ -2732,7 +2712,7 @@ void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local
Object::cast_to<InputEventMouseMotion>(*ev) ||
Object::cast_to<InputEventScreenDrag>(*ev) ||
Object::cast_to<InputEventScreenTouch>(*ev) ||
- Object::cast_to<InputEventKey>(*ev) //to remember state
+ Object::cast_to<InputEventKey>(*ev) // To remember state.
)) {
physics_picking_events.push_back(ev);
@@ -2778,10 +2758,6 @@ Variant Viewport::gui_get_drag_data() const {
}
TypedArray<String> Viewport::get_configuration_warnings() const {
- /*if (get_parent() && !Object::cast_to<Control>(get_parent()) && !render_target) {
- return TTR("This viewport is not set as render target. If you intend for it to display its contents directly to the screen, make it a child of a Control so it can obtain a size. Otherwise, make it a RenderTarget and assign its internal texture to some node for display.");
- }*/
-
TypedArray<String> warnings = Node::get_configuration_warnings();
if (size.x == 0 || size.y == 0) {
@@ -3132,7 +3108,7 @@ void Viewport::_listener_3d_make_next_current(Listener3D *p_exclude) {
E->get()->make_current();
}
} else {
- // Attempt to reset listener to the camera position
+ // Attempt to reset listener to the camera position.
if (camera_3d != nullptr) {
_update_listener_3d();
_camera_3d_transform_changed_notify();
@@ -3145,11 +3121,11 @@ void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Cam
Transform3D camera_transform = p_camera->get_global_transform();
ObjectID id = p_object->get_instance_id();
- //avoid sending the fake event unnecessarily if nothing really changed in the context
+ // Avoid sending the fake event unnecessarily if nothing really changed in the context.
if (object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) {
Ref<InputEventMouseMotion> mm = p_input_event;
if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
- return; //discarded
+ return; // Discarded.
}
}
p_object->_input_event_call(camera_3d, p_input_event, p_pos, p_normal, p_shape);
@@ -3745,10 +3721,8 @@ Viewport::Viewport() {
viewport_textures.insert(default_texture.ptr());
default_texture->proxy = RS::get_singleton()->texture_proxy_create(texture_rid);
- //internal_listener_2d = SpatialSound2DServer::get_singleton()->listener_create();
- canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport)
+ canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport).
- //clear=true;
set_shadow_atlas_size(shadow_atlas_size);
for (int i = 0; i < 4; i++) {
@@ -3776,11 +3750,11 @@ Viewport::Viewport() {
set_scale_3d((Scale3D)scale);
#endif // _3D_DISABLED
- set_sdf_oversize(sdf_oversize); //set to server
+ set_sdf_oversize(sdf_oversize); // Set to server.
}
Viewport::~Viewport() {
- //erase itself from viewport textures
+ // Erase itself from viewport textures.
for (Set<ViewportTexture *>::Element *E = viewport_textures.front(); E; E = E->next()) {
E->get()->vp = nullptr;
}
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index ad589a605e..71d0c69d55 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -543,6 +543,7 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BITS);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 27b0eb098b..aa4ed1cb13 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -105,6 +105,7 @@ public:
ARRAY_FORMAT_BLEND_SHAPE_MASK = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK,
ARRAY_FORMAT_CUSTOM_BASE = RS::ARRAY_FORMAT_CUSTOM_BASE,
+ ARRAY_FORMAT_CUSTOM_BITS = RS::ARRAY_FORMAT_CUSTOM_BITS,
ARRAY_FORMAT_CUSTOM0_SHIFT = RS::ARRAY_FORMAT_CUSTOM0_SHIFT,
ARRAY_FORMAT_CUSTOM1_SHIFT = RS::ARRAY_FORMAT_CUSTOM1_SHIFT,
ARRAY_FORMAT_CUSTOM2_SHIFT = RS::ARRAY_FORMAT_CUSTOM2_SHIFT,
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 875aa30824..d5e370568d 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -409,7 +409,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = CLAMP(int32_t(c.r * 255.0), 0, 255);
w[idx * 4 + 1] = CLAMP(int32_t(c.g * 255.0), 0, 255);
w[idx * 4 + 2] = CLAMP(int32_t(c.b * 255.0), 0, 255);
@@ -426,7 +426,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = uint8_t(int8_t(CLAMP(int32_t(c.r * 127.0), -128, 127)));
w[idx * 4 + 1] = uint8_t(int8_t(CLAMP(int32_t(c.g * 127.0), -128, 127)));
w[idx * 4 + 2] = uint8_t(int8_t(CLAMP(int32_t(c.b * 127.0), -128, 127)));
@@ -443,7 +443,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 2 + 0] = Math::make_half_float(c.r);
w[idx * 2 + 1] = Math::make_half_float(c.g);
}
@@ -458,7 +458,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = Math::make_half_float(c.r);
w[idx * 4 + 1] = Math::make_half_float(c.g);
w[idx * 4 + 2] = Math::make_half_float(c.b);
@@ -475,7 +475,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx] = c.r;
}
@@ -489,7 +489,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 2 + 0] = c.r;
w[idx * 2 + 1] = c.g;
}
@@ -504,7 +504,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 3 + 0] = c.r;
w[idx * 3 + 1] = c.g;
w[idx * 3 + 2] = c.b;
@@ -520,7 +520,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = c.r;
w[idx * 4 + 1] = c.g;
w[idx * 4 + 2] = c.b;
@@ -679,6 +679,9 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, Local
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
+static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
+static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
+
void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, LocalVector<SurfaceTool::Vertex> &ret, uint32_t *r_format) {
ret.clear();
@@ -733,8 +736,6 @@ void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays
if (warr.size()) {
lformat |= RS::ARRAY_FORMAT_WEIGHTS;
}
- static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
- static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
ERR_CONTINUE_MSG(p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_BYTE_ARRAY, "Extracting Byte/Half formats is not supported");
@@ -832,6 +833,12 @@ 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);
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ last_custom_format[j] = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ }
+ }
}
void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) {
@@ -841,6 +848,12 @@ void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) {
primitive = p_existing->surface_get_primitive_type(p_surface);
_create_list(p_existing, p_surface, &vertex_array, &index_array, format);
material = p_existing->surface_get_material(p_surface);
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ last_custom_format[j] = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ }
+ }
}
void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name) {
@@ -863,6 +876,12 @@ void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_sur
Array mesh = arr[shape_idx];
ERR_FAIL_COND(mesh.size() != RS::ARRAY_MAX);
_create_list_from_arrays(arr[shape_idx], &vertex_array, &index_array, format);
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ last_custom_format[j] = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ }
+ }
}
void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform3D &p_xform) {
@@ -878,6 +897,16 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
LocalVector<int> nindices;
_create_list(p_existing, p_surface, &nvertices, &nindices, nformat);
format |= nformat;
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ CustomFormat new_format = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ if (last_custom_format[j] != CUSTOM_MAX && last_custom_format[j] != new_format) {
+ WARN_PRINT(vformat("Custom %d format %d mismatch when appending format %d", j, last_custom_format[j], new_format));
+ }
+ last_custom_format[j] = new_format;
+ }
+ }
int vfrom = vertex_array.size();
for (uint32_t vi = 0; vi < nvertices.size(); vi++) {
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index a24860996c..d0f02b44cb 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -601,10 +601,10 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.usage_defines["UV2"] = "#define UV2_USED\n";
actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n";
actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n";
- actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n";
- actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
- actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
- actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
+ actions.usage_defines["CUSTOM0"] = "#define CUSTOM0_USED\n";
+ actions.usage_defines["CUSTOM1"] = "#define CUSTOM1_USED\n";
+ actions.usage_defines["CUSTOM2"] = "#define CUSTOM2_USED\n";
+ actions.usage_defines["CUSTOM3"] = "#define CUSTOM3_USED\n";
actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 14b3b6d9aa..cd314d8c56 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -593,10 +593,10 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
actions.usage_defines["UV2"] = "#define UV2_USED\n";
actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n";
actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n";
- actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n";
- actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
- actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
- actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
+ actions.usage_defines["CUSTOM0"] = "#define CUSTOM0_USED\n";
+ actions.usage_defines["CUSTOM1"] = "#define CUSTOM1_USED\n";
+ actions.usage_defines["CUSTOM2"] = "#define CUSTOM2_USED\n";
+ actions.usage_defines["CUSTOM3"] = "#define CUSTOM3_USED\n";
actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index db0011aa60..5f349e5e33 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -500,7 +500,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case RS::ARRAY_CUSTOM1:
case RS::ARRAY_CUSTOM2:
case RS::ARRAY_CUSTOM3: {
- uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (RS::ARRAY_CUSTOM0 - ai))) & ARRAY_FORMAT_CUSTOM_MASK;
+ uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (ai - RS::ARRAY_CUSTOM0))) & ARRAY_FORMAT_CUSTOM_MASK;
switch (type) {
case ARRAY_CUSTOM_RGBA8_UNORM:
case ARRAY_CUSTOM_RGBA8_SNORM:
@@ -541,14 +541,14 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<float> array = p_arrays[ai];
- int32_t s = ARRAY_CUSTOM_R_FLOAT - ai + 1;
+ int32_t s = type - ARRAY_CUSTOM_R_FLOAT + 1;
ERR_FAIL_COND_V(array.size() != p_vertex_array_len * s, ERR_INVALID_PARAMETER);
const float *src = array.ptr();
for (int i = 0; i < p_vertex_array_len; i++) {
- memcpy(&aw[p_offsets[ai] + i * p_attrib_stride], &src[i * s], 4 * s);
+ memcpy(&aw[p_offsets[ai] + i * p_attrib_stride], &src[i * s], sizeof(float) * s);
}
} break;
default: {
@@ -938,6 +938,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
}
+ for (uint32_t i = 0; i < RS::ARRAY_CUSTOM_COUNT; ++i) {
+ // include custom array format type.
+ if (format & (1 << (ARRAY_CUSTOM0 + i))) {
+ format |= (RS::ARRAY_FORMAT_CUSTOM_MASK << (RS::ARRAY_FORMAT_CUSTOM_BASE + i * RS::ARRAY_FORMAT_CUSTOM_BITS)) & p_compress_format;
+ }
+ }
+
uint32_t offsets[RS::ARRAY_MAX];
uint32_t vertex_element_size;
@@ -1191,7 +1198,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
case RS::ARRAY_CUSTOM1:
case RS::ARRAY_CUSTOM2:
case RS::ARRAY_CUSTOM3: {
- uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (RS::ARRAY_CUSTOM0 - i))) & ARRAY_FORMAT_CUSTOM_MASK;
+ uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (i - RS::ARRAY_CUSTOM0))) & ARRAY_FORMAT_CUSTOM_MASK;
switch (type) {
case ARRAY_CUSTOM_RGBA8_UNORM:
case ARRAY_CUSTOM_RGBA8_SNORM:
@@ -1219,6 +1226,8 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
uint32_t s = type - ARRAY_CUSTOM_R_FLOAT + 1;
Vector<float> arr;
+ arr.resize(s * p_vertex_len);
+
float *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {