Skip to content

Commit 094fa88

Browse files
committed
Add support for custom 0-1 attributes to ImmediateMesh
1 parent 9a5d6d1 commit 094fa88

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

doc/classes/ImmediateMesh.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
[/csharp]
2626
[/codeblocks]
2727
[b]Note:[/b] Generating complex geometries with [ImmediateMesh] is highly inefficient. Instead, it is designed to generate simple geometry that changes often.
28+
[b]Note:[/b] The custom data attributes will use the [constant Mesh.ARRAY_CUSTOM_RGBA_FLOAT] format.
2829
</description>
2930
<tutorials>
3031
<link title="Using ImmediateMesh">$DOCS_URL/tutorials/3d/procedural_geometry/immediatemesh.html</link>
@@ -71,6 +72,20 @@
7172
Set the color attribute that will be pushed with the next vertex.
7273
</description>
7374
</method>
75+
<method name="surface_set_custom0">
76+
<return type="void" />
77+
<param index="0" name="custom0" type="Vector4" />
78+
<description>
79+
Set the CUSTOM0 attribute that will be pushed with the next vertex.
80+
</description>
81+
</method>
82+
<method name="surface_set_custom1">
83+
<return type="void" />
84+
<param index="0" name="custom1" type="Vector4" />
85+
<description>
86+
Set the CUSTOM1 attribute that will be pushed with the next vertex.
87+
</description>
88+
</method>
7489
<method name="surface_set_normal">
7590
<return type="void" />
7691
<param index="0" name="normal" type="Vector3" />

scene/resources/immediate_mesh.cpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,30 @@ void ImmediateMesh::surface_set_uv2(const Vector2 &p_uv2) {
9898

9999
current_uv2 = p_uv2;
100100
}
101+
void ImmediateMesh::surface_set_custom0(const Vector4 &p_custom0) {
102+
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
103+
if (!uses_custom0) {
104+
custom0s.resize(vertices.size());
105+
for (Vector4 &custom0 : custom0s) {
106+
custom0 = p_custom0;
107+
}
108+
uses_custom0 = true;
109+
}
110+
111+
current_custom0 = p_custom0;
112+
}
113+
void ImmediateMesh::surface_set_custom1(const Vector4 &p_custom1) {
114+
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
115+
if (!uses_custom1) {
116+
custom1s.resize(vertices.size());
117+
for (Vector4 &custom1 : custom1s) {
118+
custom1 = p_custom1;
119+
}
120+
uses_custom1 = true;
121+
}
122+
123+
current_custom1 = p_custom1;
124+
}
101125
void ImmediateMesh::surface_add_vertex(const Vector3 &p_vertex) {
102126
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
103127
ERR_FAIL_COND_MSG(vertices.size() && active_surface_data.vertex_2d, "Can't mix 2D and 3D vertices in a surface.");
@@ -117,6 +141,12 @@ void ImmediateMesh::surface_add_vertex(const Vector3 &p_vertex) {
117141
if (uses_uv2s) {
118142
uv2s.push_back(current_uv2);
119143
}
144+
if (uses_custom0) {
145+
custom0s.push_back(current_custom0);
146+
}
147+
if (uses_custom1) {
148+
custom1s.push_back(current_custom1);
149+
}
120150
vertices.push_back(p_vertex);
121151
}
122152

@@ -139,6 +169,12 @@ void ImmediateMesh::surface_add_vertex_2d(const Vector2 &p_vertex) {
139169
if (uses_uv2s) {
140170
uv2s.push_back(current_uv2);
141171
}
172+
if (uses_custom0) {
173+
custom0s.push_back(current_custom0);
174+
}
175+
if (uses_custom1) {
176+
custom1s.push_back(current_custom1);
177+
}
142178
Vector3 v(p_vertex.x, p_vertex.y, 0);
143179
vertices.push_back(v);
144180

@@ -245,6 +281,18 @@ void ImmediateMesh::surface_end() {
245281
uv2_offset = attribute_stride;
246282
attribute_stride += sizeof(float) * 2;
247283
}
284+
uint32_t custom0_offset = 0;
285+
if (uses_custom0) {
286+
format |= ARRAY_FORMAT_CUSTOM0 | (ARRAY_CUSTOM_RGBA_FLOAT << ARRAY_FORMAT_CUSTOM0_SHIFT);
287+
custom0_offset = attribute_stride;
288+
attribute_stride += sizeof(float) * 4;
289+
}
290+
uint32_t custom1_offset = 0;
291+
if (uses_custom1) {
292+
format |= ARRAY_FORMAT_CUSTOM1 | (ARRAY_CUSTOM_RGBA_FLOAT << ARRAY_FORMAT_CUSTOM1_SHIFT);
293+
custom1_offset = attribute_stride;
294+
attribute_stride += sizeof(float) * 4;
295+
}
248296

249297
surface_attribute_create_cache.resize(vertices.size() * attribute_stride);
250298

@@ -272,6 +320,23 @@ void ImmediateMesh::surface_end() {
272320
uv2[0] = uv2s[i].x;
273321
uv2[1] = uv2s[i].y;
274322
}
323+
324+
if (uses_custom0) {
325+
float *custom0 = (float *)&surface_attribute_ptr[i * attribute_stride + custom0_offset];
326+
327+
custom0[0] = custom0s[i].x;
328+
custom0[1] = custom0s[i].y;
329+
custom0[2] = custom0s[i].z;
330+
custom0[3] = custom0s[i].w;
331+
}
332+
if (uses_custom1) {
333+
float *custom1 = (float *)&surface_attribute_ptr[i * attribute_stride + custom1_offset];
334+
335+
custom1[0] = custom1s[i].x;
336+
custom1[1] = custom1s[i].y;
337+
custom1[2] = custom1s[i].z;
338+
custom1[3] = custom1s[i].w;
339+
}
275340
}
276341
}
277342

@@ -280,7 +345,7 @@ void ImmediateMesh::surface_end() {
280345
sd.primitive = RS::PrimitiveType(active_surface_data.primitive);
281346
sd.format = format;
282347
sd.vertex_data = surface_vertex_create_cache;
283-
if (uses_colors || uses_uvs || uses_uv2s) {
348+
if (uses_colors || uses_uvs || uses_uv2s || uses_custom0 || uses_custom1) {
284349
sd.attribute_data = surface_attribute_create_cache;
285350
}
286351
sd.vertex_count = vertices.size();
@@ -303,13 +368,17 @@ void ImmediateMesh::surface_end() {
303368
tangents.clear();
304369
uvs.clear();
305370
uv2s.clear();
371+
custom0s.clear();
372+
custom1s.clear();
306373
vertices.clear();
307374

308375
uses_colors = false;
309376
uses_normals = false;
310377
uses_tangents = false;
311378
uses_uvs = false;
312379
uses_uv2s = false;
380+
uses_custom0 = false;
381+
uses_custom1 = false;
313382

314383
surface_active = false;
315384

@@ -326,13 +395,17 @@ void ImmediateMesh::clear_surfaces() {
326395
tangents.clear();
327396
uvs.clear();
328397
uv2s.clear();
398+
custom0s.clear();
399+
custom1s.clear();
329400
vertices.clear();
330401

331402
uses_colors = false;
332403
uses_normals = false;
333404
uses_tangents = false;
334405
uses_uvs = false;
335406
uses_uv2s = false;
407+
uses_custom0 = false;
408+
uses_custom1 = false;
336409
}
337410

338411
int ImmediateMesh::get_surface_count() const {
@@ -404,6 +477,8 @@ void ImmediateMesh::_bind_methods() {
404477
ClassDB::bind_method(D_METHOD("surface_set_tangent", "tangent"), &ImmediateMesh::surface_set_tangent);
405478
ClassDB::bind_method(D_METHOD("surface_set_uv", "uv"), &ImmediateMesh::surface_set_uv);
406479
ClassDB::bind_method(D_METHOD("surface_set_uv2", "uv2"), &ImmediateMesh::surface_set_uv2);
480+
ClassDB::bind_method(D_METHOD("surface_set_custom0", "custom0"), &ImmediateMesh::surface_set_custom0);
481+
ClassDB::bind_method(D_METHOD("surface_set_custom1", "custom1"), &ImmediateMesh::surface_set_custom1);
407482
ClassDB::bind_method(D_METHOD("surface_add_vertex", "vertex"), &ImmediateMesh::surface_add_vertex);
408483
ClassDB::bind_method(D_METHOD("surface_add_vertex_2d", "vertex"), &ImmediateMesh::surface_add_vertex_2d);
409484
ClassDB::bind_method(D_METHOD("surface_end"), &ImmediateMesh::surface_end);

scene/resources/immediate_mesh.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,24 @@ class ImmediateMesh : public Mesh {
4343
bool uses_tangents = false;
4444
bool uses_uvs = false;
4545
bool uses_uv2s = false;
46+
bool uses_custom0 = false;
47+
bool uses_custom1 = false;
4648

4749
Color current_color;
4850
Vector3 current_normal;
4951
Plane current_tangent;
5052
Vector2 current_uv;
5153
Vector2 current_uv2;
54+
Vector4 current_custom0;
55+
Vector4 current_custom1;
5256

5357
LocalVector<Color> colors;
5458
LocalVector<Vector3> normals;
5559
LocalVector<Plane> tangents;
5660
LocalVector<Vector2> uvs;
5761
LocalVector<Vector2> uv2s;
62+
LocalVector<Vector4> custom0s;
63+
LocalVector<Vector4> custom1s;
5864
LocalVector<Vector3> vertices;
5965

6066
struct Surface {
@@ -86,6 +92,8 @@ class ImmediateMesh : public Mesh {
8692
void surface_set_tangent(const Plane &p_tangent);
8793
void surface_set_uv(const Vector2 &p_uv);
8894
void surface_set_uv2(const Vector2 &p_uv2);
95+
void surface_set_custom0(const Vector4 &p_custom0);
96+
void surface_set_custom1(const Vector4 &p_custom1);
8997
void surface_add_vertex(const Vector3 &p_vertex);
9098
void surface_add_vertex_2d(const Vector2 &p_vertex);
9199
void surface_end();

0 commit comments

Comments
 (0)