1/**************************************************************************/
2/* mesh_storage.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "mesh_storage.h"
32
33using namespace RendererRD;
34
35MeshStorage *MeshStorage::singleton = nullptr;
36
37MeshStorage *MeshStorage::get_singleton() {
38 return singleton;
39}
40
41MeshStorage::MeshStorage() {
42 singleton = this;
43
44 default_rd_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4);
45
46 //default rd buffers
47 {
48 Vector<uint8_t> buffer;
49 {
50 buffer.resize(sizeof(float) * 3);
51 {
52 uint8_t *w = buffer.ptrw();
53 float *fptr = reinterpret_cast<float *>(w);
54 fptr[0] = 0.0;
55 fptr[1] = 0.0;
56 fptr[2] = 0.0;
57 }
58 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_VERTEX] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
59 }
60
61 { //normal
62 buffer.resize(sizeof(float) * 3);
63 {
64 uint8_t *w = buffer.ptrw();
65 float *fptr = reinterpret_cast<float *>(w);
66 fptr[0] = 1.0;
67 fptr[1] = 0.0;
68 fptr[2] = 0.0;
69 }
70 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_NORMAL] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
71 }
72
73 { //tangent
74 buffer.resize(sizeof(float) * 4);
75 {
76 uint8_t *w = buffer.ptrw();
77 float *fptr = reinterpret_cast<float *>(w);
78 fptr[0] = 1.0;
79 fptr[1] = 0.0;
80 fptr[2] = 0.0;
81 fptr[3] = 0.0;
82 }
83 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TANGENT] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
84 }
85
86 { //color
87 buffer.resize(sizeof(float) * 4);
88 {
89 uint8_t *w = buffer.ptrw();
90 float *fptr = reinterpret_cast<float *>(w);
91 fptr[0] = 1.0;
92 fptr[1] = 1.0;
93 fptr[2] = 1.0;
94 fptr[3] = 1.0;
95 }
96 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_COLOR] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
97 }
98
99 { //tex uv 1
100 buffer.resize(sizeof(float) * 2);
101 {
102 uint8_t *w = buffer.ptrw();
103 float *fptr = reinterpret_cast<float *>(w);
104 fptr[0] = 0.0;
105 fptr[1] = 0.0;
106 }
107 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
108 }
109 { //tex uv 2
110 buffer.resize(sizeof(float) * 2);
111 {
112 uint8_t *w = buffer.ptrw();
113 float *fptr = reinterpret_cast<float *>(w);
114 fptr[0] = 0.0;
115 fptr[1] = 0.0;
116 }
117 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
118 }
119
120 for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
121 buffer.resize(sizeof(float) * 4);
122 {
123 uint8_t *w = buffer.ptrw();
124 float *fptr = reinterpret_cast<float *>(w);
125 fptr[0] = 0.0;
126 fptr[1] = 0.0;
127 fptr[2] = 0.0;
128 fptr[3] = 0.0;
129 }
130 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_CUSTOM0 + i] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
131 }
132
133 { //bones
134 buffer.resize(sizeof(uint32_t) * 4);
135 {
136 uint8_t *w = buffer.ptrw();
137 uint32_t *fptr = reinterpret_cast<uint32_t *>(w);
138 fptr[0] = 0;
139 fptr[1] = 0;
140 fptr[2] = 0;
141 fptr[3] = 0;
142 }
143 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_BONES] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
144 }
145
146 { //weights
147 buffer.resize(sizeof(float) * 4);
148 {
149 uint8_t *w = buffer.ptrw();
150 float *fptr = reinterpret_cast<float *>(w);
151 fptr[0] = 0.0;
152 fptr[1] = 0.0;
153 fptr[2] = 0.0;
154 fptr[3] = 0.0;
155 }
156 mesh_default_rd_buffers[DEFAULT_RD_BUFFER_WEIGHTS] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
157 }
158 }
159
160 {
161 Vector<String> skeleton_modes;
162 skeleton_modes.push_back("\n#define MODE_2D\n");
163 skeleton_modes.push_back("");
164
165 skeleton_shader.shader.initialize(skeleton_modes);
166 skeleton_shader.version = skeleton_shader.shader.version_create();
167 for (int i = 0; i < SkeletonShader::SHADER_MODE_MAX; i++) {
168 skeleton_shader.version_shader[i] = skeleton_shader.shader.version_get_shader(skeleton_shader.version, i);
169 skeleton_shader.pipeline[i] = RD::get_singleton()->compute_pipeline_create(skeleton_shader.version_shader[i]);
170 }
171
172 {
173 Vector<RD::Uniform> uniforms;
174 {
175 RD::Uniform u;
176 u.binding = 0;
177 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
178 u.append_id(default_rd_storage_buffer);
179 uniforms.push_back(u);
180 }
181 skeleton_shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON);
182 }
183 }
184}
185
186MeshStorage::~MeshStorage() {
187 //def buffers
188 for (int i = 0; i < DEFAULT_RD_BUFFER_MAX; i++) {
189 RD::get_singleton()->free(mesh_default_rd_buffers[i]);
190 }
191
192 skeleton_shader.shader.version_free(skeleton_shader.version);
193
194 RD::get_singleton()->free(default_rd_storage_buffer);
195
196 singleton = nullptr;
197}
198
199bool MeshStorage::free(RID p_rid) {
200 if (owns_mesh(p_rid)) {
201 mesh_free(p_rid);
202 return true;
203 } else if (owns_mesh_instance(p_rid)) {
204 mesh_instance_free(p_rid);
205 return true;
206 } else if (owns_multimesh(p_rid)) {
207 multimesh_free(p_rid);
208 return true;
209 } else if (owns_skeleton(p_rid)) {
210 skeleton_free(p_rid);
211 return true;
212 }
213
214 return false;
215}
216
217/* MESH API */
218
219RID MeshStorage::mesh_allocate() {
220 return mesh_owner.allocate_rid();
221}
222
223void MeshStorage::mesh_initialize(RID p_rid) {
224 mesh_owner.initialize_rid(p_rid, Mesh());
225}
226
227void MeshStorage::mesh_free(RID p_rid) {
228 mesh_clear(p_rid);
229 mesh_set_shadow_mesh(p_rid, RID());
230 Mesh *mesh = mesh_owner.get_or_null(p_rid);
231 ERR_FAIL_COND(!mesh);
232
233 mesh->dependency.deleted_notify(p_rid);
234 if (mesh->instances.size()) {
235 ERR_PRINT("deleting mesh with active instances");
236 }
237 if (mesh->shadow_owners.size()) {
238 for (Mesh *E : mesh->shadow_owners) {
239 Mesh *shadow_owner = E;
240 shadow_owner->shadow_mesh = RID();
241 shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
242 }
243 }
244 mesh_owner.free(p_rid);
245}
246
247void MeshStorage::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) {
248 ERR_FAIL_COND(p_blend_shape_count < 0);
249
250 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
251 ERR_FAIL_COND(!mesh);
252
253 ERR_FAIL_COND(mesh->surface_count > 0); //surfaces already exist
254
255 mesh->blend_shape_count = p_blend_shape_count;
256}
257
258/// Returns stride
259void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {
260 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
261 ERR_FAIL_COND(!mesh);
262
263 ERR_FAIL_COND(mesh->surface_count == RS::MAX_MESH_SURFACES);
264
265#ifdef DEBUG_ENABLED
266 //do a validation, to catch errors first
267 {
268 uint32_t stride = 0;
269 uint32_t attrib_stride = 0;
270 uint32_t skin_stride = 0;
271
272 for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
273 if ((p_surface.format & (1 << i))) {
274 switch (i) {
275 case RS::ARRAY_VERTEX: {
276 if (p_surface.format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
277 stride += sizeof(float) * 2;
278 } else {
279 stride += sizeof(float) * 3;
280 }
281
282 } break;
283 case RS::ARRAY_NORMAL: {
284 stride += sizeof(int32_t);
285
286 } break;
287 case RS::ARRAY_TANGENT: {
288 stride += sizeof(int32_t);
289
290 } break;
291 case RS::ARRAY_COLOR: {
292 attrib_stride += sizeof(uint32_t);
293 } break;
294 case RS::ARRAY_TEX_UV: {
295 attrib_stride += sizeof(float) * 2;
296
297 } break;
298 case RS::ARRAY_TEX_UV2: {
299 attrib_stride += sizeof(float) * 2;
300
301 } break;
302 case RS::ARRAY_CUSTOM0:
303 case RS::ARRAY_CUSTOM1:
304 case RS::ARRAY_CUSTOM2:
305 case RS::ARRAY_CUSTOM3: {
306 int idx = i - RS::ARRAY_CUSTOM0;
307 const uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
308 uint32_t fmt = (p_surface.format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
309 const uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
310 attrib_stride += fmtsize[fmt];
311
312 } break;
313 case RS::ARRAY_WEIGHTS:
314 case RS::ARRAY_BONES: {
315 //uses a separate array
316 bool use_8 = p_surface.format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
317 skin_stride += sizeof(int16_t) * (use_8 ? 16 : 8);
318 } break;
319 }
320 }
321 }
322
323 int expected_size = stride * p_surface.vertex_count;
324 ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of vertex data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
325
326 int bs_expected_size = expected_size * mesh->blend_shape_count;
327
328 ERR_FAIL_COND_MSG(bs_expected_size != p_surface.blend_shape_data.size(), "Size of blend shape data provided (" + itos(p_surface.blend_shape_data.size()) + ") does not match expected (" + itos(bs_expected_size) + ")");
329
330 int expected_attrib_size = attrib_stride * p_surface.vertex_count;
331 ERR_FAIL_COND_MSG(expected_attrib_size != p_surface.attribute_data.size(), "Size of attribute data provided (" + itos(p_surface.attribute_data.size()) + ") does not match expected (" + itos(expected_attrib_size) + ")");
332
333 if ((p_surface.format & RS::ARRAY_FORMAT_WEIGHTS) && (p_surface.format & RS::ARRAY_FORMAT_BONES)) {
334 expected_size = skin_stride * p_surface.vertex_count;
335 ERR_FAIL_COND_MSG(expected_size != p_surface.skin_data.size(), "Size of skin data provided (" + itos(p_surface.skin_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
336 }
337 }
338
339#endif
340
341 Mesh::Surface *s = memnew(Mesh::Surface);
342
343 s->format = p_surface.format;
344 s->primitive = p_surface.primitive;
345
346 bool use_as_storage = (p_surface.skin_data.size() || mesh->blend_shape_count > 0);
347
348 if (p_surface.vertex_data.size()) {
349 s->vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.vertex_data.size(), p_surface.vertex_data, use_as_storage);
350 s->vertex_buffer_size = p_surface.vertex_data.size();
351 }
352
353 if (p_surface.attribute_data.size()) {
354 s->attribute_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.attribute_data.size(), p_surface.attribute_data);
355 }
356 if (p_surface.skin_data.size()) {
357 s->skin_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.skin_data.size(), p_surface.skin_data, use_as_storage);
358 s->skin_buffer_size = p_surface.skin_data.size();
359 }
360
361 s->vertex_count = p_surface.vertex_count;
362
363 if (p_surface.format & RS::ARRAY_FORMAT_BONES) {
364 mesh->has_bone_weights = true;
365 }
366
367 if (p_surface.index_count) {
368 bool is_index_16 = p_surface.vertex_count <= 65536 && p_surface.vertex_count > 0;
369
370 s->index_buffer = RD::get_singleton()->index_buffer_create(p_surface.index_count, is_index_16 ? RD::INDEX_BUFFER_FORMAT_UINT16 : RD::INDEX_BUFFER_FORMAT_UINT32, p_surface.index_data, false);
371 s->index_count = p_surface.index_count;
372 s->index_array = RD::get_singleton()->index_array_create(s->index_buffer, 0, s->index_count);
373 if (p_surface.lods.size()) {
374 s->lods = memnew_arr(Mesh::Surface::LOD, p_surface.lods.size());
375 s->lod_count = p_surface.lods.size();
376
377 for (int i = 0; i < p_surface.lods.size(); i++) {
378 uint32_t indices = p_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4);
379 s->lods[i].index_buffer = RD::get_singleton()->index_buffer_create(indices, is_index_16 ? RD::INDEX_BUFFER_FORMAT_UINT16 : RD::INDEX_BUFFER_FORMAT_UINT32, p_surface.lods[i].index_data);
380 s->lods[i].index_array = RD::get_singleton()->index_array_create(s->lods[i].index_buffer, 0, indices);
381 s->lods[i].edge_length = p_surface.lods[i].edge_length;
382 s->lods[i].index_count = indices;
383 }
384 }
385 }
386
387 ERR_FAIL_COND_MSG(!p_surface.index_count && !p_surface.vertex_count, "Meshes must contain a vertex array, an index array, or both");
388
389 s->aabb = p_surface.aabb;
390 s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them.
391
392 if (mesh->blend_shape_count > 0) {
393 s->blend_shape_buffer = RD::get_singleton()->storage_buffer_create(p_surface.blend_shape_data.size(), p_surface.blend_shape_data);
394 }
395
396 if (use_as_storage) {
397 Vector<RD::Uniform> uniforms;
398 {
399 RD::Uniform u;
400 u.binding = 0;
401 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
402 if (s->vertex_buffer.is_valid()) {
403 u.append_id(s->vertex_buffer);
404 } else {
405 u.append_id(default_rd_storage_buffer);
406 }
407 uniforms.push_back(u);
408 }
409 {
410 RD::Uniform u;
411 u.binding = 1;
412 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
413 if (s->skin_buffer.is_valid()) {
414 u.append_id(s->skin_buffer);
415 } else {
416 u.append_id(default_rd_storage_buffer);
417 }
418 uniforms.push_back(u);
419 }
420 {
421 RD::Uniform u;
422 u.binding = 2;
423 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
424 if (s->blend_shape_buffer.is_valid()) {
425 u.append_id(s->blend_shape_buffer);
426 } else {
427 u.append_id(default_rd_storage_buffer);
428 }
429 uniforms.push_back(u);
430 }
431
432 s->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SURFACE);
433 }
434
435 if (mesh->surface_count == 0) {
436 mesh->aabb = p_surface.aabb;
437 } else {
438 mesh->aabb.merge_with(p_surface.aabb);
439 }
440 mesh->skeleton_aabb_version = 0;
441
442 s->material = p_surface.material;
443
444 mesh->surfaces = (Mesh::Surface **)memrealloc(mesh->surfaces, sizeof(Mesh::Surface *) * (mesh->surface_count + 1));
445 mesh->surfaces[mesh->surface_count] = s;
446 mesh->surface_count++;
447
448 for (MeshInstance *mi : mesh->instances) {
449 _mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);
450 }
451
452 mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
453
454 for (Mesh *E : mesh->shadow_owners) {
455 Mesh *shadow_owner = E;
456 shadow_owner->shadow_mesh = RID();
457 shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
458 }
459
460 mesh->material_cache.clear();
461}
462
463int MeshStorage::mesh_get_blend_shape_count(RID p_mesh) const {
464 const Mesh *mesh = mesh_owner.get_or_null(p_mesh);
465 ERR_FAIL_COND_V(!mesh, -1);
466 return mesh->blend_shape_count;
467}
468
469void MeshStorage::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) {
470 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
471 ERR_FAIL_COND(!mesh);
472 ERR_FAIL_INDEX((int)p_mode, 2);
473
474 mesh->blend_shape_mode = p_mode;
475}
476
477RS::BlendShapeMode MeshStorage::mesh_get_blend_shape_mode(RID p_mesh) const {
478 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
479 ERR_FAIL_COND_V(!mesh, RS::BLEND_SHAPE_MODE_NORMALIZED);
480 return mesh->blend_shape_mode;
481}
482
483void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
484 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
485 ERR_FAIL_COND(!mesh);
486 ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
487 ERR_FAIL_COND(p_data.size() == 0);
488 ERR_FAIL_COND(mesh->surfaces[p_surface]->vertex_buffer.is_null());
489 uint64_t data_size = p_data.size();
490 const uint8_t *r = p_data.ptr();
491
492 RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->vertex_buffer, p_offset, data_size, r);
493}
494
495void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
496 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
497 ERR_FAIL_COND(!mesh);
498 ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
499 ERR_FAIL_COND(p_data.size() == 0);
500 ERR_FAIL_COND(mesh->surfaces[p_surface]->attribute_buffer.is_null());
501 uint64_t data_size = p_data.size();
502 const uint8_t *r = p_data.ptr();
503
504 RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->attribute_buffer, p_offset, data_size, r);
505}
506
507void MeshStorage::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
508 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
509 ERR_FAIL_COND(!mesh);
510 ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
511 ERR_FAIL_COND(p_data.size() == 0);
512 ERR_FAIL_COND(mesh->surfaces[p_surface]->skin_buffer.is_null());
513 uint64_t data_size = p_data.size();
514 const uint8_t *r = p_data.ptr();
515
516 RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->skin_buffer, p_offset, data_size, r);
517}
518
519void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
520 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
521 ERR_FAIL_COND(!mesh);
522 ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
523 mesh->surfaces[p_surface]->material = p_material;
524
525 mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
526 mesh->material_cache.clear();
527}
528
529RID MeshStorage::mesh_surface_get_material(RID p_mesh, int p_surface) const {
530 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
531 ERR_FAIL_COND_V(!mesh, RID());
532 ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RID());
533
534 return mesh->surfaces[p_surface]->material;
535}
536
537RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
538 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
539 ERR_FAIL_COND_V(!mesh, RS::SurfaceData());
540 ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData());
541
542 Mesh::Surface &s = *mesh->surfaces[p_surface];
543
544 RS::SurfaceData sd;
545 sd.format = s.format;
546 if (s.vertex_buffer.is_valid()) {
547 sd.vertex_data = RD::get_singleton()->buffer_get_data(s.vertex_buffer);
548 }
549 if (s.attribute_buffer.is_valid()) {
550 sd.attribute_data = RD::get_singleton()->buffer_get_data(s.attribute_buffer);
551 }
552 if (s.skin_buffer.is_valid()) {
553 sd.skin_data = RD::get_singleton()->buffer_get_data(s.skin_buffer);
554 }
555 sd.vertex_count = s.vertex_count;
556 sd.index_count = s.index_count;
557 sd.primitive = s.primitive;
558
559 if (sd.index_count) {
560 sd.index_data = RD::get_singleton()->buffer_get_data(s.index_buffer);
561 }
562 sd.aabb = s.aabb;
563 for (uint32_t i = 0; i < s.lod_count; i++) {
564 RS::SurfaceData::LOD lod;
565 lod.edge_length = s.lods[i].edge_length;
566 lod.index_data = RD::get_singleton()->buffer_get_data(s.lods[i].index_buffer);
567 sd.lods.push_back(lod);
568 }
569
570 sd.bone_aabbs = s.bone_aabbs;
571
572 if (s.blend_shape_buffer.is_valid()) {
573 sd.blend_shape_data = RD::get_singleton()->buffer_get_data(s.blend_shape_buffer);
574 }
575
576 return sd;
577}
578
579int MeshStorage::mesh_get_surface_count(RID p_mesh) const {
580 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
581 ERR_FAIL_COND_V(!mesh, 0);
582 return mesh->surface_count;
583}
584
585void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
586 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
587 ERR_FAIL_COND(!mesh);
588 mesh->custom_aabb = p_aabb;
589
590 mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
591}
592
593AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const {
594 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
595 ERR_FAIL_COND_V(!mesh, AABB());
596 return mesh->custom_aabb;
597}
598
599AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
600 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
601 ERR_FAIL_COND_V(!mesh, AABB());
602
603 if (mesh->custom_aabb != AABB()) {
604 return mesh->custom_aabb;
605 }
606
607 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
608
609 if (!skeleton || skeleton->size == 0 || mesh->skeleton_aabb_version == skeleton->version) {
610 return mesh->aabb;
611 }
612
613 AABB aabb;
614
615 for (uint32_t i = 0; i < mesh->surface_count; i++) {
616 AABB laabb;
617 if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->bone_aabbs.size()) {
618 int bs = mesh->surfaces[i]->bone_aabbs.size();
619 const AABB *skbones = mesh->surfaces[i]->bone_aabbs.ptr();
620
621 int sbs = skeleton->size;
622 ERR_CONTINUE(bs > sbs);
623 const float *baseptr = skeleton->data.ptr();
624
625 bool first = true;
626
627 if (skeleton->use_2d) {
628 for (int j = 0; j < bs; j++) {
629 if (skbones[j].size == Vector3(-1, -1, -1)) {
630 continue; //bone is unused
631 }
632
633 const float *dataptr = baseptr + j * 8;
634
635 Transform3D mtx;
636
637 mtx.basis.rows[0][0] = dataptr[0];
638 mtx.basis.rows[0][1] = dataptr[1];
639 mtx.origin.x = dataptr[3];
640
641 mtx.basis.rows[1][0] = dataptr[4];
642 mtx.basis.rows[1][1] = dataptr[5];
643 mtx.origin.y = dataptr[7];
644
645 AABB baabb = mtx.xform(skbones[j]);
646
647 if (first) {
648 laabb = baabb;
649 first = false;
650 } else {
651 laabb.merge_with(baabb);
652 }
653 }
654 } else {
655 for (int j = 0; j < bs; j++) {
656 if (skbones[j].size == Vector3(-1, -1, -1)) {
657 continue; //bone is unused
658 }
659
660 const float *dataptr = baseptr + j * 12;
661
662 Transform3D mtx;
663
664 mtx.basis.rows[0][0] = dataptr[0];
665 mtx.basis.rows[0][1] = dataptr[1];
666 mtx.basis.rows[0][2] = dataptr[2];
667 mtx.origin.x = dataptr[3];
668 mtx.basis.rows[1][0] = dataptr[4];
669 mtx.basis.rows[1][1] = dataptr[5];
670 mtx.basis.rows[1][2] = dataptr[6];
671 mtx.origin.y = dataptr[7];
672 mtx.basis.rows[2][0] = dataptr[8];
673 mtx.basis.rows[2][1] = dataptr[9];
674 mtx.basis.rows[2][2] = dataptr[10];
675 mtx.origin.z = dataptr[11];
676
677 AABB baabb = mtx.xform(skbones[j]);
678 if (first) {
679 laabb = baabb;
680 first = false;
681 } else {
682 laabb.merge_with(baabb);
683 }
684 }
685 }
686
687 if (laabb.size == Vector3()) {
688 laabb = mesh->surfaces[i]->aabb;
689 }
690 } else {
691 laabb = mesh->surfaces[i]->aabb;
692 }
693
694 if (i == 0) {
695 aabb = laabb;
696 } else {
697 aabb.merge_with(laabb);
698 }
699 }
700
701 mesh->aabb = aabb;
702
703 mesh->skeleton_aabb_version = skeleton->version;
704 return aabb;
705}
706
707void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
708 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
709 ERR_FAIL_COND(!mesh);
710
711 Mesh *shadow_mesh = mesh_owner.get_or_null(mesh->shadow_mesh);
712 if (shadow_mesh) {
713 shadow_mesh->shadow_owners.erase(mesh);
714 }
715 mesh->shadow_mesh = p_shadow_mesh;
716
717 shadow_mesh = mesh_owner.get_or_null(mesh->shadow_mesh);
718
719 if (shadow_mesh) {
720 shadow_mesh->shadow_owners.insert(mesh);
721 }
722
723 mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
724}
725
726void MeshStorage::mesh_clear(RID p_mesh) {
727 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
728 ERR_FAIL_COND(!mesh);
729
730 // Clear instance data before mesh data.
731 for (MeshInstance *mi : mesh->instances) {
732 _mesh_instance_clear(mi);
733 }
734
735 for (uint32_t i = 0; i < mesh->surface_count; i++) {
736 Mesh::Surface &s = *mesh->surfaces[i];
737 if (s.vertex_buffer.is_valid()) {
738 RD::get_singleton()->free(s.vertex_buffer); //clears arrays as dependency automatically, including all versions
739 }
740 if (s.attribute_buffer.is_valid()) {
741 RD::get_singleton()->free(s.attribute_buffer);
742 }
743 if (s.skin_buffer.is_valid()) {
744 RD::get_singleton()->free(s.skin_buffer);
745 }
746 if (s.versions) {
747 memfree(s.versions); //reallocs, so free with memfree.
748 }
749
750 if (s.index_buffer.is_valid()) {
751 RD::get_singleton()->free(s.index_buffer);
752 }
753
754 if (s.lod_count) {
755 for (uint32_t j = 0; j < s.lod_count; j++) {
756 RD::get_singleton()->free(s.lods[j].index_buffer);
757 }
758 memdelete_arr(s.lods);
759 }
760
761 if (s.blend_shape_buffer.is_valid()) {
762 RD::get_singleton()->free(s.blend_shape_buffer);
763 }
764
765 memdelete(mesh->surfaces[i]);
766 }
767 if (mesh->surfaces) {
768 memfree(mesh->surfaces);
769 }
770
771 mesh->surfaces = nullptr;
772 mesh->surface_count = 0;
773 mesh->material_cache.clear();
774 mesh->has_bone_weights = false;
775 mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
776
777 for (Mesh *E : mesh->shadow_owners) {
778 Mesh *shadow_owner = E;
779 shadow_owner->shadow_mesh = RID();
780 shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
781 }
782}
783
784bool MeshStorage::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) {
785 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
786 ERR_FAIL_COND_V(!mesh, false);
787
788 return mesh->blend_shape_count > 0 || (mesh->has_bone_weights && p_has_skeleton);
789}
790
791Dependency *MeshStorage::mesh_get_dependency(RID p_mesh) const {
792 Mesh *mesh = mesh_owner.get_or_null(p_mesh);
793 ERR_FAIL_COND_V(!mesh, nullptr);
794
795 return &mesh->dependency;
796}
797
798/* MESH INSTANCE */
799
800RID MeshStorage::mesh_instance_create(RID p_base) {
801 Mesh *mesh = mesh_owner.get_or_null(p_base);
802 ERR_FAIL_COND_V(!mesh, RID());
803
804 RID rid = mesh_instance_owner.make_rid();
805 MeshInstance *mi = mesh_instance_owner.get_or_null(rid);
806
807 mi->mesh = mesh;
808
809 for (uint32_t i = 0; i < mesh->surface_count; i++) {
810 _mesh_instance_add_surface(mi, mesh, i);
811 }
812
813 mi->I = mesh->instances.push_back(mi);
814
815 mi->dirty = true;
816
817 return rid;
818}
819
820void MeshStorage::mesh_instance_free(RID p_rid) {
821 MeshInstance *mi = mesh_instance_owner.get_or_null(p_rid);
822 _mesh_instance_clear(mi);
823 mi->mesh->instances.erase(mi->I);
824 mi->I = nullptr;
825
826 mesh_instance_owner.free(p_rid);
827}
828
829void MeshStorage::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {
830 MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
831 if (mi->skeleton == p_skeleton) {
832 return;
833 }
834 mi->skeleton = p_skeleton;
835 mi->skeleton_version = 0;
836 mi->dirty = true;
837}
838
839void MeshStorage::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) {
840 MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
841 ERR_FAIL_COND(!mi);
842 ERR_FAIL_INDEX(p_shape, (int)mi->blend_weights.size());
843 mi->blend_weights[p_shape] = p_weight;
844 mi->weights_dirty = true;
845 //will be eventually updated
846}
847
848void MeshStorage::_mesh_instance_clear(MeshInstance *mi) {
849 for (const RendererRD::MeshStorage::MeshInstance::Surface &surface : mi->surfaces) {
850 if (surface.versions) {
851 for (uint32_t j = 0; j < surface.version_count; j++) {
852 RD::get_singleton()->free(surface.versions[j].vertex_array);
853 }
854 memfree(surface.versions);
855 }
856
857 for (uint32_t i = 0; i < 2; i++) {
858 if (surface.vertex_buffer[i].is_valid()) {
859 RD::get_singleton()->free(surface.vertex_buffer[i]);
860 }
861 }
862 }
863 mi->surfaces.clear();
864
865 if (mi->blend_weights_buffer.is_valid()) {
866 RD::get_singleton()->free(mi->blend_weights_buffer);
867 mi->blend_weights_buffer = RID();
868 }
869 mi->blend_weights.clear();
870 mi->weights_dirty = false;
871 mi->skeleton_version = 0;
872}
873
874void MeshStorage::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface) {
875 if (mesh->blend_shape_count > 0 && mi->blend_weights_buffer.is_null()) {
876 mi->blend_weights.resize(mesh->blend_shape_count);
877 for (float &weight : mi->blend_weights) {
878 weight = 0;
879 }
880 mi->blend_weights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(float) * mi->blend_weights.size(), mi->blend_weights.to_byte_array());
881 mi->weights_dirty = true;
882 }
883
884 MeshInstance::Surface s;
885 if ((mesh->blend_shape_count > 0 || (mesh->surfaces[p_surface]->format & RS::ARRAY_FORMAT_BONES)) && mesh->surfaces[p_surface]->vertex_buffer_size > 0) {
886 _mesh_instance_add_surface_buffer(mi, mesh, &s, p_surface, 0);
887 }
888
889 mi->surfaces.push_back(s);
890 mi->dirty = true;
891}
892
893void MeshStorage::_mesh_instance_add_surface_buffer(MeshInstance *mi, Mesh *mesh, MeshInstance::Surface *s, uint32_t p_surface, uint32_t p_buffer_index) {
894 s->vertex_buffer[p_buffer_index] = RD::get_singleton()->vertex_buffer_create(mesh->surfaces[p_surface]->vertex_buffer_size, Vector<uint8_t>(), true);
895
896 Vector<RD::Uniform> uniforms;
897 {
898 RD::Uniform u;
899 u.binding = 1;
900 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
901 u.append_id(s->vertex_buffer[p_buffer_index]);
902 uniforms.push_back(u);
903 }
904 {
905 RD::Uniform u;
906 u.binding = 2;
907 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
908 if (mi->blend_weights_buffer.is_valid()) {
909 u.append_id(mi->blend_weights_buffer);
910 } else {
911 u.append_id(default_rd_storage_buffer);
912 }
913 uniforms.push_back(u);
914 }
915 s->uniform_set[p_buffer_index] = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_INSTANCE);
916}
917
918void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) {
919 MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
920
921 bool needs_update = mi->dirty;
922
923 if (mi->weights_dirty && !mi->weight_update_list.in_list()) {
924 dirty_mesh_instance_weights.add(&mi->weight_update_list);
925 needs_update = true;
926 }
927
928 if (mi->array_update_list.in_list()) {
929 return;
930 }
931
932 if (!needs_update && mi->skeleton.is_valid()) {
933 Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton);
934 if (sk && sk->version != mi->skeleton_version) {
935 needs_update = true;
936 }
937 }
938
939 if (needs_update) {
940 dirty_mesh_instance_arrays.add(&mi->array_update_list);
941 }
942}
943
944void MeshStorage::mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) {
945 MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
946 mi->canvas_item_transform_2d = p_transform;
947}
948
949void MeshStorage::update_mesh_instances() {
950 while (dirty_mesh_instance_weights.first()) {
951 MeshInstance *mi = dirty_mesh_instance_weights.first()->self();
952
953 if (mi->blend_weights_buffer.is_valid()) {
954 RD::get_singleton()->buffer_update(mi->blend_weights_buffer, 0, mi->blend_weights.size() * sizeof(float), mi->blend_weights.ptr());
955 }
956 dirty_mesh_instance_weights.remove(&mi->weight_update_list);
957 mi->weights_dirty = false;
958 }
959 if (dirty_mesh_instance_arrays.first() == nullptr) {
960 return; //nothing to do
961 }
962
963 //process skeletons and blend shapes
964 uint64_t frame = RSG::rasterizer->get_frame_number();
965 bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0);
966 RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
967
968 while (dirty_mesh_instance_arrays.first()) {
969 MeshInstance *mi = dirty_mesh_instance_arrays.first()->self();
970
971 Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton);
972
973 for (uint32_t i = 0; i < mi->surfaces.size(); i++) {
974 if (mi->surfaces[i].uniform_set[0].is_null() || mi->mesh->surfaces[i]->uniform_set.is_null()) {
975 // Skip over mesh instances that don't require their own uniform buffers.
976 continue;
977 }
978
979 mi->surfaces[i].previous_buffer = mi->surfaces[i].current_buffer;
980
981 if (uses_motion_vectors && (frame - mi->surfaces[i].last_change) == 1) {
982 // Previous buffer's data can only be one frame old to be able to use motion vectors.
983 uint32_t new_buffer_index = mi->surfaces[i].current_buffer ^ 1;
984
985 if (mi->surfaces[i].uniform_set[new_buffer_index].is_null()) {
986 // Create the new vertex buffer on demand where the result for the current frame will be stored.
987 _mesh_instance_add_surface_buffer(mi, mi->mesh, &mi->surfaces[i], i, new_buffer_index);
988 }
989
990 mi->surfaces[i].current_buffer = new_buffer_index;
991 }
992
993 mi->surfaces[i].last_change = frame;
994
995 RID mi_surface_uniform_set = mi->surfaces[i].uniform_set[mi->surfaces[i].current_buffer];
996 if (mi_surface_uniform_set.is_null()) {
997 continue;
998 }
999
1000 bool array_is_2d = mi->mesh->surfaces[i]->format & RS::ARRAY_FLAG_USE_2D_VERTICES;
1001
1002 RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, skeleton_shader.pipeline[array_is_2d ? SkeletonShader::SHADER_MODE_2D : SkeletonShader::SHADER_MODE_3D]);
1003
1004 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mi_surface_uniform_set, SkeletonShader::UNIFORM_SET_INSTANCE);
1005 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mi->mesh->surfaces[i]->uniform_set, SkeletonShader::UNIFORM_SET_SURFACE);
1006 if (sk && sk->uniform_set_mi.is_valid()) {
1007 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sk->uniform_set_mi, SkeletonShader::UNIFORM_SET_SKELETON);
1008 } else {
1009 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, skeleton_shader.default_skeleton_uniform_set, SkeletonShader::UNIFORM_SET_SKELETON);
1010 }
1011
1012 SkeletonShader::PushConstant push_constant;
1013
1014 push_constant.has_normal = mi->mesh->surfaces[i]->format & RS::ARRAY_FORMAT_NORMAL;
1015 push_constant.has_tangent = mi->mesh->surfaces[i]->format & RS::ARRAY_FORMAT_TANGENT;
1016 push_constant.has_skeleton = sk != nullptr && sk->use_2d == array_is_2d && (mi->mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES);
1017 push_constant.has_blend_shape = mi->mesh->blend_shape_count > 0;
1018
1019 push_constant.vertex_count = mi->mesh->surfaces[i]->vertex_count;
1020 push_constant.vertex_stride = (mi->mesh->surfaces[i]->vertex_buffer_size / mi->mesh->surfaces[i]->vertex_count) / 4;
1021 push_constant.skin_stride = (mi->mesh->surfaces[i]->skin_buffer_size / mi->mesh->surfaces[i]->vertex_count) / 4;
1022 push_constant.skin_weight_offset = (mi->mesh->surfaces[i]->format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 4 : 2;
1023
1024 Transform2D transform = Transform2D();
1025 if (sk && sk->use_2d) {
1026 transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;
1027 }
1028 push_constant.skeleton_transform_x[0] = transform.columns[0][0];
1029 push_constant.skeleton_transform_x[1] = transform.columns[0][1];
1030 push_constant.skeleton_transform_y[0] = transform.columns[1][0];
1031 push_constant.skeleton_transform_y[1] = transform.columns[1][1];
1032 push_constant.skeleton_transform_offset[0] = transform.columns[2][0];
1033 push_constant.skeleton_transform_offset[1] = transform.columns[2][1];
1034
1035 Transform2D inverse_transform = transform.affine_inverse();
1036 push_constant.inverse_transform_x[0] = inverse_transform.columns[0][0];
1037 push_constant.inverse_transform_x[1] = inverse_transform.columns[0][1];
1038 push_constant.inverse_transform_y[0] = inverse_transform.columns[1][0];
1039 push_constant.inverse_transform_y[1] = inverse_transform.columns[1][1];
1040 push_constant.inverse_transform_offset[0] = inverse_transform.columns[2][0];
1041 push_constant.inverse_transform_offset[1] = inverse_transform.columns[2][1];
1042
1043 push_constant.blend_shape_count = mi->mesh->blend_shape_count;
1044 push_constant.normalized_blend_shapes = mi->mesh->blend_shape_mode == RS::BLEND_SHAPE_MODE_NORMALIZED;
1045 push_constant.pad0 = 0;
1046 push_constant.pad1 = 0;
1047
1048 RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SkeletonShader::PushConstant));
1049
1050 //dispatch without barrier, so all is done at the same time
1051 RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1);
1052 }
1053
1054 mi->dirty = false;
1055 if (sk) {
1056 mi->skeleton_version = sk->version;
1057 }
1058 dirty_mesh_instance_arrays.remove(&mi->array_update_list);
1059 }
1060
1061 RD::get_singleton()->compute_list_end();
1062}
1063
1064void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::Version &v, Mesh::Surface *s, uint32_t p_input_mask, bool p_input_motion_vectors, MeshInstance::Surface *mis) {
1065 Vector<RD::VertexAttribute> attributes;
1066 Vector<RID> buffers;
1067
1068 uint32_t stride = 0;
1069 uint32_t attribute_stride = 0;
1070 uint32_t skin_stride = 0;
1071
1072 for (int i = 0; i < RS::ARRAY_INDEX; i++) {
1073 RD::VertexAttribute vd;
1074 RID buffer;
1075 vd.location = i;
1076
1077 if (!(s->format & (1 << i))) {
1078 // Not supplied by surface, use default value
1079 buffer = mesh_default_rd_buffers[i];
1080 vd.stride = 0;
1081 switch (i) {
1082 case RS::ARRAY_VERTEX: {
1083 vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
1084
1085 } break;
1086 case RS::ARRAY_NORMAL: {
1087 vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
1088 } break;
1089 case RS::ARRAY_TANGENT: {
1090 vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
1091 } break;
1092 case RS::ARRAY_COLOR: {
1093 vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
1094
1095 } break;
1096 case RS::ARRAY_TEX_UV: {
1097 vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
1098
1099 } break;
1100 case RS::ARRAY_TEX_UV2: {
1101 vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
1102 } break;
1103 case RS::ARRAY_CUSTOM0:
1104 case RS::ARRAY_CUSTOM1:
1105 case RS::ARRAY_CUSTOM2:
1106 case RS::ARRAY_CUSTOM3: {
1107 //assumed weights too
1108 vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
1109 } break;
1110 case RS::ARRAY_BONES: {
1111 //assumed weights too
1112 vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
1113 } break;
1114 case RS::ARRAY_WEIGHTS: {
1115 //assumed weights too
1116 vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
1117 } break;
1118 }
1119 } else {
1120 //Supplied, use it
1121
1122 vd.stride = 1; //mark that it needs a stride set (default uses 0)
1123
1124 switch (i) {
1125 case RS::ARRAY_VERTEX: {
1126 vd.offset = stride;
1127
1128 if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
1129 vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
1130 stride += sizeof(float) * 2;
1131 } else {
1132 vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
1133 stride += sizeof(float) * 3;
1134 }
1135
1136 if (mis) {
1137 buffer = mis->vertex_buffer[mis->current_buffer];
1138 } else {
1139 buffer = s->vertex_buffer;
1140 }
1141
1142 } break;
1143 case RS::ARRAY_NORMAL: {
1144 vd.offset = stride;
1145 vd.format = RD::DATA_FORMAT_R16G16_UNORM;
1146 stride += sizeof(uint16_t) * 2;
1147
1148 if (mis) {
1149 buffer = mis->vertex_buffer[mis->current_buffer];
1150 } else {
1151 buffer = s->vertex_buffer;
1152 }
1153 } break;
1154 case RS::ARRAY_TANGENT: {
1155 vd.offset = stride;
1156 vd.format = RD::DATA_FORMAT_R16G16_UNORM;
1157 stride += sizeof(uint16_t) * 2;
1158
1159 if (mis) {
1160 buffer = mis->vertex_buffer[mis->current_buffer];
1161 } else {
1162 buffer = s->vertex_buffer;
1163 }
1164 } break;
1165 case RS::ARRAY_COLOR: {
1166 vd.offset = attribute_stride;
1167
1168 vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1169 attribute_stride += sizeof(int8_t) * 4;
1170 buffer = s->attribute_buffer;
1171 } break;
1172 case RS::ARRAY_TEX_UV: {
1173 vd.offset = attribute_stride;
1174
1175 vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
1176 attribute_stride += sizeof(float) * 2;
1177 buffer = s->attribute_buffer;
1178
1179 } break;
1180 case RS::ARRAY_TEX_UV2: {
1181 vd.offset = attribute_stride;
1182
1183 vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
1184 attribute_stride += sizeof(float) * 2;
1185 buffer = s->attribute_buffer;
1186 } break;
1187 case RS::ARRAY_CUSTOM0:
1188 case RS::ARRAY_CUSTOM1:
1189 case RS::ARRAY_CUSTOM2:
1190 case RS::ARRAY_CUSTOM3: {
1191 vd.offset = attribute_stride;
1192
1193 int idx = i - RS::ARRAY_CUSTOM0;
1194 const uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
1195 uint32_t fmt = (s->format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
1196 const uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
1197 const RD::DataFormat fmtrd[RS::ARRAY_CUSTOM_MAX] = { RD::DATA_FORMAT_R8G8B8A8_UNORM, RD::DATA_FORMAT_R8G8B8A8_SNORM, RD::DATA_FORMAT_R16G16_SFLOAT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::DATA_FORMAT_R32_SFLOAT, RD::DATA_FORMAT_R32G32_SFLOAT, RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::DATA_FORMAT_R32G32B32A32_SFLOAT };
1198 vd.format = fmtrd[fmt];
1199 attribute_stride += fmtsize[fmt];
1200 buffer = s->attribute_buffer;
1201 } break;
1202 case RS::ARRAY_BONES: {
1203 vd.offset = skin_stride;
1204
1205 vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
1206 skin_stride += sizeof(int16_t) * 4;
1207 buffer = s->skin_buffer;
1208 } break;
1209 case RS::ARRAY_WEIGHTS: {
1210 vd.offset = skin_stride;
1211
1212 vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
1213 skin_stride += sizeof(int16_t) * 4;
1214 buffer = s->skin_buffer;
1215 } break;
1216 }
1217 }
1218
1219 if (!(p_input_mask & (1 << i))) {
1220 continue; // Shader does not need this, skip it (but computing stride was important anyway)
1221 }
1222
1223 attributes.push_back(vd);
1224 buffers.push_back(buffer);
1225
1226 if (p_input_motion_vectors) {
1227 // Since the previous vertex, normal and tangent can't be part of the vertex format but they are required when motion
1228 // vectors are enabled, we opt to push a copy of the vertex attribute with a different location and buffer (if it's
1229 // part of an instance that has one).
1230 switch (i) {
1231 case RS::ARRAY_VERTEX: {
1232 vd.location = ATTRIBUTE_LOCATION_PREV_VERTEX;
1233 } break;
1234 case RS::ARRAY_NORMAL: {
1235 vd.location = ATTRIBUTE_LOCATION_PREV_NORMAL;
1236 } break;
1237 case RS::ARRAY_TANGENT: {
1238 vd.location = ATTRIBUTE_LOCATION_PREV_TANGENT;
1239 } break;
1240 }
1241
1242 if (int(vd.location) != i) {
1243 if (mis && buffer != mesh_default_rd_buffers[i]) {
1244 buffer = mis->vertex_buffer[mis->previous_buffer];
1245 }
1246
1247 attributes.push_back(vd);
1248 buffers.push_back(buffer);
1249 }
1250 }
1251 }
1252
1253 //update final stride
1254 for (int i = 0; i < attributes.size(); i++) {
1255 if (attributes[i].stride == 0) {
1256 continue; //default location
1257 }
1258 int loc = attributes[i].location;
1259
1260 if ((loc < RS::ARRAY_COLOR) || ((loc >= ATTRIBUTE_LOCATION_PREV_VERTEX) && (loc <= ATTRIBUTE_LOCATION_PREV_TANGENT))) {
1261 attributes.write[i].stride = stride;
1262 } else if (loc < RS::ARRAY_BONES) {
1263 attributes.write[i].stride = attribute_stride;
1264 } else {
1265 attributes.write[i].stride = skin_stride;
1266 }
1267 }
1268
1269 v.input_mask = p_input_mask;
1270 v.current_buffer = mis ? mis->current_buffer : 0;
1271 v.previous_buffer = mis ? mis->previous_buffer : 0;
1272 v.input_motion_vectors = p_input_motion_vectors;
1273 v.vertex_format = RD::get_singleton()->vertex_format_create(attributes);
1274 v.vertex_array = RD::get_singleton()->vertex_array_create(s->vertex_count, v.vertex_format, buffers);
1275}
1276
1277////////////////// MULTIMESH
1278
1279RID MeshStorage::multimesh_allocate() {
1280 return multimesh_owner.allocate_rid();
1281}
1282void MeshStorage::multimesh_initialize(RID p_rid) {
1283 multimesh_owner.initialize_rid(p_rid, MultiMesh());
1284}
1285
1286void MeshStorage::multimesh_free(RID p_rid) {
1287 _update_dirty_multimeshes();
1288 multimesh_allocate_data(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D);
1289 MultiMesh *multimesh = multimesh_owner.get_or_null(p_rid);
1290 multimesh->dependency.deleted_notify(p_rid);
1291 multimesh_owner.free(p_rid);
1292}
1293
1294void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
1295 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1296 ERR_FAIL_COND(!multimesh);
1297
1298 if (multimesh->instances == p_instances && multimesh->xform_format == p_transform_format && multimesh->uses_colors == p_use_colors && multimesh->uses_custom_data == p_use_custom_data) {
1299 return;
1300 }
1301
1302 if (multimesh->buffer.is_valid()) {
1303 RD::get_singleton()->free(multimesh->buffer);
1304 multimesh->buffer = RID();
1305 multimesh->uniform_set_2d = RID(); //cleared by dependency
1306 multimesh->uniform_set_3d = RID(); //cleared by dependency
1307 }
1308
1309 if (multimesh->data_cache_dirty_regions) {
1310 memdelete_arr(multimesh->data_cache_dirty_regions);
1311 multimesh->data_cache_dirty_regions = nullptr;
1312 multimesh->data_cache_dirty_region_count = 0;
1313 }
1314
1315 if (multimesh->previous_data_cache_dirty_regions) {
1316 memdelete_arr(multimesh->previous_data_cache_dirty_regions);
1317 multimesh->previous_data_cache_dirty_regions = nullptr;
1318 multimesh->previous_data_cache_dirty_region_count = 0;
1319 }
1320
1321 multimesh->instances = p_instances;
1322 multimesh->xform_format = p_transform_format;
1323 multimesh->uses_colors = p_use_colors;
1324 multimesh->color_offset_cache = p_transform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;
1325 multimesh->uses_custom_data = p_use_custom_data;
1326 multimesh->custom_data_offset_cache = multimesh->color_offset_cache + (p_use_colors ? 4 : 0);
1327 multimesh->stride_cache = multimesh->custom_data_offset_cache + (p_use_custom_data ? 4 : 0);
1328 multimesh->buffer_set = false;
1329
1330 //print_line("allocate, elements: " + itos(p_instances) + " 2D: " + itos(p_transform_format == RS::MULTIMESH_TRANSFORM_2D) + " colors " + itos(multimesh->uses_colors) + " data " + itos(multimesh->uses_custom_data) + " stride " + itos(multimesh->stride_cache) + " total size " + itos(multimesh->stride_cache * multimesh->instances));
1331 multimesh->data_cache = Vector<float>();
1332 multimesh->aabb = AABB();
1333 multimesh->aabb_dirty = false;
1334 multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances);
1335 multimesh->motion_vectors_current_offset = 0;
1336 multimesh->motion_vectors_previous_offset = 0;
1337 multimesh->motion_vectors_last_change = -1;
1338
1339 if (multimesh->instances) {
1340 uint32_t buffer_size = multimesh->instances * multimesh->stride_cache * sizeof(float);
1341 if (multimesh->motion_vectors_enabled) {
1342 buffer_size *= 2;
1343 }
1344 multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size);
1345 }
1346
1347 multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH);
1348}
1349
1350void MeshStorage::_multimesh_enable_motion_vectors(MultiMesh *multimesh) {
1351 if (multimesh->motion_vectors_enabled) {
1352 return;
1353 }
1354
1355 multimesh->motion_vectors_enabled = true;
1356
1357 multimesh->motion_vectors_current_offset = 0;
1358 multimesh->motion_vectors_previous_offset = 0;
1359 multimesh->motion_vectors_last_change = -1;
1360
1361 if (!multimesh->data_cache.is_empty()) {
1362 multimesh->data_cache.append_array(multimesh->data_cache);
1363 }
1364
1365 uint32_t buffer_size = multimesh->instances * multimesh->stride_cache * sizeof(float);
1366 uint32_t new_buffer_size = buffer_size * 2;
1367 RID new_buffer = RD::get_singleton()->storage_buffer_create(new_buffer_size);
1368
1369 if (multimesh->buffer_set && multimesh->data_cache.is_empty()) {
1370 // If the buffer was set but there's no data cached in the CPU, we copy the buffer directly on the GPU.
1371 RD::get_singleton()->barrier();
1372 RD::get_singleton()->buffer_copy(multimesh->buffer, new_buffer, 0, 0, buffer_size, RD::BARRIER_MASK_NO_BARRIER);
1373 RD::get_singleton()->buffer_copy(multimesh->buffer, new_buffer, 0, buffer_size, buffer_size);
1374 } else if (!multimesh->data_cache.is_empty()) {
1375 // Simply upload the data cached in the CPU, which should already be doubled in size.
1376 ERR_FAIL_COND(multimesh->data_cache.size() * sizeof(float) != size_t(new_buffer_size));
1377 RD::get_singleton()->buffer_update(new_buffer, 0, new_buffer_size, multimesh->data_cache.ptr());
1378 }
1379
1380 if (multimesh->buffer.is_valid()) {
1381 RD::get_singleton()->free(multimesh->buffer);
1382 }
1383
1384 multimesh->buffer = new_buffer;
1385 multimesh->uniform_set_3d = RID(); // Cleared by dependency.
1386
1387 // Invalidate any references to the buffer that was released and the uniform set that was pointing to it.
1388 multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH);
1389}
1390
1391void MeshStorage::_multimesh_get_motion_vectors_offsets(RID p_multimesh, uint32_t &r_current_offset, uint32_t &r_prev_offset) {
1392 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1393 ERR_FAIL_COND(!multimesh);
1394 r_current_offset = multimesh->motion_vectors_current_offset;
1395 if (RSG::rasterizer->get_frame_number() - multimesh->motion_vectors_last_change >= 2) {
1396 multimesh->motion_vectors_previous_offset = multimesh->motion_vectors_current_offset;
1397 }
1398 r_prev_offset = multimesh->motion_vectors_previous_offset;
1399}
1400
1401int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const {
1402 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1403 ERR_FAIL_COND_V(!multimesh, 0);
1404 return multimesh->instances;
1405}
1406
1407void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
1408 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1409 ERR_FAIL_COND(!multimesh);
1410 if (multimesh->mesh == p_mesh) {
1411 return;
1412 }
1413 multimesh->mesh = p_mesh;
1414
1415 if (multimesh->instances == 0) {
1416 return;
1417 }
1418
1419 if (multimesh->data_cache.size()) {
1420 //we have a data cache, just mark it dirt
1421 _multimesh_mark_all_dirty(multimesh, false, true);
1422 } else if (multimesh->instances) {
1423 //need to re-create AABB unfortunately, calling this has a penalty
1424 if (multimesh->buffer_set) {
1425 Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
1426 const uint8_t *r = buffer.ptr() + multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float);
1427 const float *data = reinterpret_cast<const float *>(r);
1428 _multimesh_re_create_aabb(multimesh, data, multimesh->instances);
1429 }
1430 }
1431
1432 multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
1433}
1434
1435#define MULTIMESH_DIRTY_REGION_SIZE 512
1436
1437void MeshStorage::_multimesh_make_local(MultiMesh *multimesh) const {
1438 if (multimesh->data_cache.size() > 0) {
1439 return; //already local
1440 }
1441
1442 // this means that the user wants to load/save individual elements,
1443 // for this, the data must reside on CPU, so just copy it there.
1444 uint32_t buffer_size = multimesh->instances * multimesh->stride_cache;
1445 if (multimesh->motion_vectors_enabled) {
1446 buffer_size *= 2;
1447 }
1448 multimesh->data_cache.resize(buffer_size);
1449 {
1450 float *w = multimesh->data_cache.ptrw();
1451
1452 if (multimesh->buffer_set) {
1453 Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
1454 {
1455 const uint8_t *r = buffer.ptr();
1456 memcpy(w, r, buffer.size());
1457 }
1458 } else {
1459 memset(w, 0, buffer_size * sizeof(float));
1460 }
1461 }
1462 uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
1463 multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count);
1464 memset(multimesh->data_cache_dirty_regions, 0, data_cache_dirty_region_count * sizeof(bool));
1465 multimesh->data_cache_dirty_region_count = 0;
1466
1467 multimesh->previous_data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count);
1468 memset(multimesh->previous_data_cache_dirty_regions, 0, data_cache_dirty_region_count * sizeof(bool));
1469 multimesh->previous_data_cache_dirty_region_count = 0;
1470}
1471
1472void MeshStorage::_multimesh_update_motion_vectors_data_cache(MultiMesh *multimesh) {
1473 ERR_FAIL_COND(multimesh->data_cache.is_empty());
1474
1475 if (!multimesh->motion_vectors_enabled) {
1476 return;
1477 }
1478
1479 uint32_t frame = RSG::rasterizer->get_frame_number();
1480 if (multimesh->motion_vectors_last_change != frame) {
1481 multimesh->motion_vectors_previous_offset = multimesh->motion_vectors_current_offset;
1482 multimesh->motion_vectors_current_offset = multimesh->instances - multimesh->motion_vectors_current_offset;
1483 multimesh->motion_vectors_last_change = frame;
1484
1485 if (multimesh->previous_data_cache_dirty_region_count > 0) {
1486 uint8_t *data = (uint8_t *)multimesh->data_cache.ptrw();
1487 uint32_t current_ofs = multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float);
1488 uint32_t previous_ofs = multimesh->motion_vectors_previous_offset * multimesh->stride_cache * sizeof(float);
1489 uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
1490 uint32_t visible_region_count = visible_instances == 0 ? 0 : (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
1491 uint32_t region_size = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float);
1492 uint32_t size = multimesh->stride_cache * (uint32_t)multimesh->instances * (uint32_t)sizeof(float);
1493 for (uint32_t i = 0; i < visible_region_count; i++) {
1494 if (multimesh->previous_data_cache_dirty_regions[i]) {
1495 uint32_t offset = i * region_size;
1496 memcpy(data + current_ofs + offset, data + previous_ofs + offset, MIN(region_size, size - offset));
1497 }
1498 }
1499 }
1500 }
1501}
1502
1503void MeshStorage::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) {
1504 uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE;
1505#ifdef DEBUG_ENABLED
1506 uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
1507 ERR_FAIL_UNSIGNED_INDEX(region_index, data_cache_dirty_region_count); //bug
1508#endif
1509 if (!multimesh->data_cache_dirty_regions[region_index]) {
1510 multimesh->data_cache_dirty_regions[region_index] = true;
1511 multimesh->data_cache_dirty_region_count++;
1512 }
1513
1514 if (p_aabb) {
1515 multimesh->aabb_dirty = true;
1516 }
1517
1518 if (!multimesh->dirty) {
1519 multimesh->dirty_list = multimesh_dirty_list;
1520 multimesh_dirty_list = multimesh;
1521 multimesh->dirty = true;
1522 }
1523}
1524
1525void MeshStorage::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) {
1526 if (p_data) {
1527 uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
1528
1529 for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {
1530 if (!multimesh->data_cache_dirty_regions[i]) {
1531 multimesh->data_cache_dirty_regions[i] = true;
1532 multimesh->data_cache_dirty_region_count++;
1533 }
1534 }
1535 }
1536
1537 if (p_aabb) {
1538 multimesh->aabb_dirty = true;
1539 }
1540
1541 if (!multimesh->dirty) {
1542 multimesh->dirty_list = multimesh_dirty_list;
1543 multimesh_dirty_list = multimesh;
1544 multimesh->dirty = true;
1545 }
1546}
1547
1548void MeshStorage::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) {
1549 ERR_FAIL_COND(multimesh->mesh.is_null());
1550 AABB aabb;
1551 AABB mesh_aabb = mesh_get_aabb(multimesh->mesh);
1552 for (int i = 0; i < p_instances; i++) {
1553 const float *data = p_data + multimesh->stride_cache * i;
1554 Transform3D t;
1555
1556 if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {
1557 t.basis.rows[0][0] = data[0];
1558 t.basis.rows[0][1] = data[1];
1559 t.basis.rows[0][2] = data[2];
1560 t.origin.x = data[3];
1561 t.basis.rows[1][0] = data[4];
1562 t.basis.rows[1][1] = data[5];
1563 t.basis.rows[1][2] = data[6];
1564 t.origin.y = data[7];
1565 t.basis.rows[2][0] = data[8];
1566 t.basis.rows[2][1] = data[9];
1567 t.basis.rows[2][2] = data[10];
1568 t.origin.z = data[11];
1569
1570 } else {
1571 t.basis.rows[0][0] = data[0];
1572 t.basis.rows[0][1] = data[1];
1573 t.origin.x = data[3];
1574
1575 t.basis.rows[1][0] = data[4];
1576 t.basis.rows[1][1] = data[5];
1577 t.origin.y = data[7];
1578 }
1579
1580 if (i == 0) {
1581 aabb = t.xform(mesh_aabb);
1582 } else {
1583 aabb.merge_with(t.xform(mesh_aabb));
1584 }
1585 }
1586
1587 multimesh->aabb = aabb;
1588}
1589
1590void MeshStorage::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) {
1591 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1592 ERR_FAIL_COND(!multimesh);
1593 ERR_FAIL_INDEX(p_index, multimesh->instances);
1594 ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D);
1595
1596 _multimesh_make_local(multimesh);
1597
1598 bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0);
1599 if (uses_motion_vectors) {
1600 _multimesh_enable_motion_vectors(multimesh);
1601 }
1602
1603 _multimesh_update_motion_vectors_data_cache(multimesh);
1604
1605 {
1606 float *w = multimesh->data_cache.ptrw();
1607
1608 float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache;
1609
1610 dataptr[0] = p_transform.basis.rows[0][0];
1611 dataptr[1] = p_transform.basis.rows[0][1];
1612 dataptr[2] = p_transform.basis.rows[0][2];
1613 dataptr[3] = p_transform.origin.x;
1614 dataptr[4] = p_transform.basis.rows[1][0];
1615 dataptr[5] = p_transform.basis.rows[1][1];
1616 dataptr[6] = p_transform.basis.rows[1][2];
1617 dataptr[7] = p_transform.origin.y;
1618 dataptr[8] = p_transform.basis.rows[2][0];
1619 dataptr[9] = p_transform.basis.rows[2][1];
1620 dataptr[10] = p_transform.basis.rows[2][2];
1621 dataptr[11] = p_transform.origin.z;
1622 }
1623
1624 _multimesh_mark_dirty(multimesh, p_index, true);
1625}
1626
1627void MeshStorage::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {
1628 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1629 ERR_FAIL_COND(!multimesh);
1630 ERR_FAIL_INDEX(p_index, multimesh->instances);
1631 ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D);
1632
1633 _multimesh_make_local(multimesh);
1634 _multimesh_update_motion_vectors_data_cache(multimesh);
1635
1636 {
1637 float *w = multimesh->data_cache.ptrw();
1638
1639 float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache;
1640
1641 dataptr[0] = p_transform.columns[0][0];
1642 dataptr[1] = p_transform.columns[1][0];
1643 dataptr[2] = 0;
1644 dataptr[3] = p_transform.columns[2][0];
1645 dataptr[4] = p_transform.columns[0][1];
1646 dataptr[5] = p_transform.columns[1][1];
1647 dataptr[6] = 0;
1648 dataptr[7] = p_transform.columns[2][1];
1649 }
1650
1651 _multimesh_mark_dirty(multimesh, p_index, true);
1652}
1653
1654void MeshStorage::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
1655 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1656 ERR_FAIL_COND(!multimesh);
1657 ERR_FAIL_INDEX(p_index, multimesh->instances);
1658 ERR_FAIL_COND(!multimesh->uses_colors);
1659
1660 _multimesh_make_local(multimesh);
1661 _multimesh_update_motion_vectors_data_cache(multimesh);
1662
1663 {
1664 float *w = multimesh->data_cache.ptrw();
1665
1666 float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->color_offset_cache;
1667
1668 dataptr[0] = p_color.r;
1669 dataptr[1] = p_color.g;
1670 dataptr[2] = p_color.b;
1671 dataptr[3] = p_color.a;
1672 }
1673
1674 _multimesh_mark_dirty(multimesh, p_index, false);
1675}
1676
1677void MeshStorage::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {
1678 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1679 ERR_FAIL_COND(!multimesh);
1680 ERR_FAIL_INDEX(p_index, multimesh->instances);
1681 ERR_FAIL_COND(!multimesh->uses_custom_data);
1682
1683 _multimesh_make_local(multimesh);
1684 _multimesh_update_motion_vectors_data_cache(multimesh);
1685
1686 {
1687 float *w = multimesh->data_cache.ptrw();
1688
1689 float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->custom_data_offset_cache;
1690
1691 dataptr[0] = p_color.r;
1692 dataptr[1] = p_color.g;
1693 dataptr[2] = p_color.b;
1694 dataptr[3] = p_color.a;
1695 }
1696
1697 _multimesh_mark_dirty(multimesh, p_index, false);
1698}
1699
1700RID MeshStorage::multimesh_get_mesh(RID p_multimesh) const {
1701 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1702 ERR_FAIL_COND_V(!multimesh, RID());
1703
1704 return multimesh->mesh;
1705}
1706
1707Dependency *MeshStorage::multimesh_get_dependency(RID p_multimesh) const {
1708 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1709 ERR_FAIL_COND_V(!multimesh, nullptr);
1710
1711 return &multimesh->dependency;
1712}
1713
1714Transform3D MeshStorage::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
1715 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1716 ERR_FAIL_COND_V(!multimesh, Transform3D());
1717 ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform3D());
1718 ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform3D());
1719
1720 _multimesh_make_local(multimesh);
1721
1722 Transform3D t;
1723 {
1724 const float *r = multimesh->data_cache.ptr();
1725
1726 const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache;
1727
1728 t.basis.rows[0][0] = dataptr[0];
1729 t.basis.rows[0][1] = dataptr[1];
1730 t.basis.rows[0][2] = dataptr[2];
1731 t.origin.x = dataptr[3];
1732 t.basis.rows[1][0] = dataptr[4];
1733 t.basis.rows[1][1] = dataptr[5];
1734 t.basis.rows[1][2] = dataptr[6];
1735 t.origin.y = dataptr[7];
1736 t.basis.rows[2][0] = dataptr[8];
1737 t.basis.rows[2][1] = dataptr[9];
1738 t.basis.rows[2][2] = dataptr[10];
1739 t.origin.z = dataptr[11];
1740 }
1741
1742 return t;
1743}
1744
1745Transform2D MeshStorage::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
1746 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1747 ERR_FAIL_COND_V(!multimesh, Transform2D());
1748 ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D());
1749 ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D, Transform2D());
1750
1751 _multimesh_make_local(multimesh);
1752
1753 Transform2D t;
1754 {
1755 const float *r = multimesh->data_cache.ptr();
1756
1757 const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache;
1758
1759 t.columns[0][0] = dataptr[0];
1760 t.columns[1][0] = dataptr[1];
1761 t.columns[2][0] = dataptr[3];
1762 t.columns[0][1] = dataptr[4];
1763 t.columns[1][1] = dataptr[5];
1764 t.columns[2][1] = dataptr[7];
1765 }
1766
1767 return t;
1768}
1769
1770Color MeshStorage::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
1771 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1772 ERR_FAIL_COND_V(!multimesh, Color());
1773 ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
1774 ERR_FAIL_COND_V(!multimesh->uses_colors, Color());
1775
1776 _multimesh_make_local(multimesh);
1777
1778 Color c;
1779 {
1780 const float *r = multimesh->data_cache.ptr();
1781
1782 const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->color_offset_cache;
1783
1784 c.r = dataptr[0];
1785 c.g = dataptr[1];
1786 c.b = dataptr[2];
1787 c.a = dataptr[3];
1788 }
1789
1790 return c;
1791}
1792
1793Color MeshStorage::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
1794 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1795 ERR_FAIL_COND_V(!multimesh, Color());
1796 ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
1797 ERR_FAIL_COND_V(!multimesh->uses_custom_data, Color());
1798
1799 _multimesh_make_local(multimesh);
1800
1801 Color c;
1802 {
1803 const float *r = multimesh->data_cache.ptr();
1804
1805 const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->custom_data_offset_cache;
1806
1807 c.r = dataptr[0];
1808 c.g = dataptr[1];
1809 c.b = dataptr[2];
1810 c.a = dataptr[3];
1811 }
1812
1813 return c;
1814}
1815
1816void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {
1817 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1818 ERR_FAIL_COND(!multimesh);
1819 ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));
1820
1821 bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0);
1822 if (uses_motion_vectors) {
1823 _multimesh_enable_motion_vectors(multimesh);
1824 }
1825
1826 if (multimesh->motion_vectors_enabled) {
1827 uint32_t frame = RSG::rasterizer->get_frame_number();
1828
1829 if (multimesh->motion_vectors_last_change != frame) {
1830 multimesh->motion_vectors_previous_offset = multimesh->motion_vectors_current_offset;
1831 multimesh->motion_vectors_current_offset = multimesh->instances - multimesh->motion_vectors_current_offset;
1832 multimesh->motion_vectors_last_change = frame;
1833 }
1834 }
1835
1836 {
1837 const float *r = p_buffer.ptr();
1838 RD::get_singleton()->buffer_update(multimesh->buffer, multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float), p_buffer.size() * sizeof(float), r);
1839 multimesh->buffer_set = true;
1840 }
1841
1842 if (multimesh->data_cache.size()) {
1843 float *cache_data = multimesh->data_cache.ptrw();
1844 memcpy(cache_data + (multimesh->motion_vectors_current_offset * multimesh->stride_cache), p_buffer.ptr(), p_buffer.size() * sizeof(float));
1845 _multimesh_mark_all_dirty(multimesh, true, true); //update AABB
1846 } else if (multimesh->mesh.is_valid()) {
1847 //if we have a mesh set, we need to re-generate the AABB from the new data
1848 const float *data = p_buffer.ptr();
1849
1850 _multimesh_re_create_aabb(multimesh, data, multimesh->instances);
1851 multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
1852 }
1853}
1854
1855Vector<float> MeshStorage::multimesh_get_buffer(RID p_multimesh) const {
1856 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1857 ERR_FAIL_COND_V(!multimesh, Vector<float>());
1858 if (multimesh->buffer.is_null()) {
1859 return Vector<float>();
1860 } else {
1861 Vector<float> ret;
1862 ret.resize(multimesh->instances * multimesh->stride_cache);
1863 float *w = ret.ptrw();
1864
1865 if (multimesh->data_cache.size()) {
1866 const uint8_t *r = (uint8_t *)multimesh->data_cache.ptr() + multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float);
1867 memcpy(w, r, ret.size() * sizeof(float));
1868 } else {
1869 Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
1870 const uint8_t *r = buffer.ptr() + multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float);
1871 memcpy(w, r, ret.size() * sizeof(float));
1872 }
1873 return ret;
1874 }
1875}
1876
1877void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
1878 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1879 ERR_FAIL_COND(!multimesh);
1880 ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances);
1881 if (multimesh->visible_instances == p_visible) {
1882 return;
1883 }
1884
1885 if (multimesh->data_cache.size()) {
1886 // There is a data cache, but we may need to update some sections.
1887 _multimesh_mark_all_dirty(multimesh, false, true);
1888 int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
1889 for (int i = start; i < p_visible; i++) {
1890 _multimesh_mark_dirty(multimesh, i, true);
1891 }
1892 }
1893
1894 multimesh->visible_instances = p_visible;
1895
1896 multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
1897}
1898
1899int MeshStorage::multimesh_get_visible_instances(RID p_multimesh) const {
1900 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1901 ERR_FAIL_COND_V(!multimesh, 0);
1902 return multimesh->visible_instances;
1903}
1904
1905AABB MeshStorage::multimesh_get_aabb(RID p_multimesh) const {
1906 MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
1907 ERR_FAIL_COND_V(!multimesh, AABB());
1908 if (multimesh->aabb_dirty) {
1909 const_cast<MeshStorage *>(this)->_update_dirty_multimeshes();
1910 }
1911 return multimesh->aabb;
1912}
1913
1914void MeshStorage::_update_dirty_multimeshes() {
1915 while (multimesh_dirty_list) {
1916 MultiMesh *multimesh = multimesh_dirty_list;
1917
1918 if (multimesh->data_cache.size()) { //may have been cleared, so only process if it exists
1919
1920 uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
1921 uint32_t buffer_offset = multimesh->motion_vectors_current_offset * multimesh->stride_cache;
1922 const float *data = multimesh->data_cache.ptr() + buffer_offset;
1923
1924 uint32_t total_dirty_regions = multimesh->data_cache_dirty_region_count + multimesh->previous_data_cache_dirty_region_count;
1925 if (total_dirty_regions != 0) {
1926 uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
1927 uint32_t visible_region_count = visible_instances == 0 ? 0 : (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
1928
1929 uint32_t region_size = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float);
1930 if (total_dirty_regions > 32 || total_dirty_regions > visible_region_count / 2) {
1931 //if there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much
1932 RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float), MIN(visible_region_count * region_size, multimesh->instances * (uint32_t)multimesh->stride_cache * (uint32_t)sizeof(float)), data);
1933 } else {
1934 //not that many regions? update them all
1935 for (uint32_t i = 0; i < visible_region_count; i++) {
1936 if (multimesh->data_cache_dirty_regions[i] || multimesh->previous_data_cache_dirty_regions[i]) {
1937 uint32_t offset = i * region_size;
1938 uint32_t size = multimesh->stride_cache * (uint32_t)multimesh->instances * (uint32_t)sizeof(float);
1939 uint32_t region_start_index = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * i;
1940 RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float) + offset, MIN(region_size, size - offset), &data[region_start_index], RD::BARRIER_MASK_NO_BARRIER);
1941 }
1942 }
1943 RD::get_singleton()->barrier(RD::BARRIER_MASK_NO_BARRIER, RD::BARRIER_MASK_ALL_BARRIERS);
1944 }
1945
1946 memcpy(multimesh->previous_data_cache_dirty_regions, multimesh->data_cache_dirty_regions, data_cache_dirty_region_count * sizeof(bool));
1947 memset(multimesh->data_cache_dirty_regions, 0, data_cache_dirty_region_count * sizeof(bool));
1948
1949 multimesh->previous_data_cache_dirty_region_count = multimesh->data_cache_dirty_region_count;
1950 multimesh->data_cache_dirty_region_count = 0;
1951 }
1952
1953 if (multimesh->aabb_dirty) {
1954 //aabb is dirty..
1955 _multimesh_re_create_aabb(multimesh, data, visible_instances);
1956 multimesh->aabb_dirty = false;
1957 multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
1958 }
1959 }
1960
1961 multimesh_dirty_list = multimesh->dirty_list;
1962
1963 multimesh->dirty_list = nullptr;
1964 multimesh->dirty = false;
1965 }
1966
1967 multimesh_dirty_list = nullptr;
1968}
1969
1970/* SKELETON API */
1971
1972RID MeshStorage::skeleton_allocate() {
1973 return skeleton_owner.allocate_rid();
1974}
1975void MeshStorage::skeleton_initialize(RID p_rid) {
1976 skeleton_owner.initialize_rid(p_rid, Skeleton());
1977}
1978
1979void MeshStorage::skeleton_free(RID p_rid) {
1980 _update_dirty_skeletons();
1981 skeleton_allocate_data(p_rid, 0);
1982 Skeleton *skeleton = skeleton_owner.get_or_null(p_rid);
1983 skeleton->dependency.deleted_notify(p_rid);
1984 skeleton_owner.free(p_rid);
1985}
1986
1987void MeshStorage::_skeleton_make_dirty(Skeleton *skeleton) {
1988 if (!skeleton->dirty) {
1989 skeleton->dirty = true;
1990 skeleton->dirty_list = skeleton_dirty_list;
1991 skeleton_dirty_list = skeleton;
1992 }
1993}
1994
1995void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
1996 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
1997 ERR_FAIL_COND(!skeleton);
1998 ERR_FAIL_COND(p_bones < 0);
1999
2000 if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) {
2001 return;
2002 }
2003
2004 skeleton->size = p_bones;
2005 skeleton->use_2d = p_2d_skeleton;
2006 skeleton->uniform_set_3d = RID();
2007
2008 if (skeleton->buffer.is_valid()) {
2009 RD::get_singleton()->free(skeleton->buffer);
2010 skeleton->buffer = RID();
2011 skeleton->data.clear();
2012 skeleton->uniform_set_mi = RID();
2013 }
2014
2015 if (skeleton->size) {
2016 skeleton->data.resize(skeleton->size * (skeleton->use_2d ? 8 : 12));
2017 skeleton->buffer = RD::get_singleton()->storage_buffer_create(skeleton->data.size() * sizeof(float));
2018 memset(skeleton->data.ptrw(), 0, skeleton->data.size() * sizeof(float));
2019
2020 _skeleton_make_dirty(skeleton);
2021
2022 {
2023 Vector<RD::Uniform> uniforms;
2024 {
2025 RD::Uniform u;
2026 u.binding = 0;
2027 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
2028 u.append_id(skeleton->buffer);
2029 uniforms.push_back(u);
2030 }
2031 skeleton->uniform_set_mi = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON);
2032 }
2033 }
2034
2035 skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_DATA);
2036}
2037
2038int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const {
2039 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
2040 ERR_FAIL_COND_V(!skeleton, 0);
2041
2042 return skeleton->size;
2043}
2044
2045void MeshStorage::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) {
2046 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
2047
2048 ERR_FAIL_COND(!skeleton);
2049 ERR_FAIL_INDEX(p_bone, skeleton->size);
2050 ERR_FAIL_COND(skeleton->use_2d);
2051
2052 float *dataptr = skeleton->data.ptrw() + p_bone * 12;
2053
2054 dataptr[0] = p_transform.basis.rows[0][0];
2055 dataptr[1] = p_transform.basis.rows[0][1];
2056 dataptr[2] = p_transform.basis.rows[0][2];
2057 dataptr[3] = p_transform.origin.x;
2058 dataptr[4] = p_transform.basis.rows[1][0];
2059 dataptr[5] = p_transform.basis.rows[1][1];
2060 dataptr[6] = p_transform.basis.rows[1][2];
2061 dataptr[7] = p_transform.origin.y;
2062 dataptr[8] = p_transform.basis.rows[2][0];
2063 dataptr[9] = p_transform.basis.rows[2][1];
2064 dataptr[10] = p_transform.basis.rows[2][2];
2065 dataptr[11] = p_transform.origin.z;
2066
2067 _skeleton_make_dirty(skeleton);
2068}
2069
2070Transform3D MeshStorage::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
2071 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
2072
2073 ERR_FAIL_COND_V(!skeleton, Transform3D());
2074 ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform3D());
2075 ERR_FAIL_COND_V(skeleton->use_2d, Transform3D());
2076
2077 const float *dataptr = skeleton->data.ptr() + p_bone * 12;
2078
2079 Transform3D t;
2080
2081 t.basis.rows[0][0] = dataptr[0];
2082 t.basis.rows[0][1] = dataptr[1];
2083 t.basis.rows[0][2] = dataptr[2];
2084 t.origin.x = dataptr[3];
2085 t.basis.rows[1][0] = dataptr[4];
2086 t.basis.rows[1][1] = dataptr[5];
2087 t.basis.rows[1][2] = dataptr[6];
2088 t.origin.y = dataptr[7];
2089 t.basis.rows[2][0] = dataptr[8];
2090 t.basis.rows[2][1] = dataptr[9];
2091 t.basis.rows[2][2] = dataptr[10];
2092 t.origin.z = dataptr[11];
2093
2094 return t;
2095}
2096
2097void MeshStorage::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
2098 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
2099
2100 ERR_FAIL_COND(!skeleton);
2101 ERR_FAIL_INDEX(p_bone, skeleton->size);
2102 ERR_FAIL_COND(!skeleton->use_2d);
2103
2104 float *dataptr = skeleton->data.ptrw() + p_bone * 8;
2105
2106 dataptr[0] = p_transform.columns[0][0];
2107 dataptr[1] = p_transform.columns[1][0];
2108 dataptr[2] = 0;
2109 dataptr[3] = p_transform.columns[2][0];
2110 dataptr[4] = p_transform.columns[0][1];
2111 dataptr[5] = p_transform.columns[1][1];
2112 dataptr[6] = 0;
2113 dataptr[7] = p_transform.columns[2][1];
2114
2115 _skeleton_make_dirty(skeleton);
2116}
2117
2118Transform2D MeshStorage::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
2119 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
2120
2121 ERR_FAIL_COND_V(!skeleton, Transform2D());
2122 ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform2D());
2123 ERR_FAIL_COND_V(!skeleton->use_2d, Transform2D());
2124
2125 const float *dataptr = skeleton->data.ptr() + p_bone * 8;
2126
2127 Transform2D t;
2128 t.columns[0][0] = dataptr[0];
2129 t.columns[1][0] = dataptr[1];
2130 t.columns[2][0] = dataptr[3];
2131 t.columns[0][1] = dataptr[4];
2132 t.columns[1][1] = dataptr[5];
2133 t.columns[2][1] = dataptr[7];
2134
2135 return t;
2136}
2137
2138void MeshStorage::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
2139 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
2140
2141 ERR_FAIL_NULL(skeleton);
2142 ERR_FAIL_COND(!skeleton->use_2d);
2143
2144 skeleton->base_transform_2d = p_base_transform;
2145}
2146
2147void MeshStorage::_update_dirty_skeletons() {
2148 while (skeleton_dirty_list) {
2149 Skeleton *skeleton = skeleton_dirty_list;
2150
2151 if (skeleton->size) {
2152 RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr());
2153 }
2154
2155 skeleton_dirty_list = skeleton->dirty_list;
2156
2157 skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_BONES);
2158
2159 skeleton->version++;
2160
2161 skeleton->dirty = false;
2162 skeleton->dirty_list = nullptr;
2163 }
2164
2165 skeleton_dirty_list = nullptr;
2166}
2167
2168void MeshStorage::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {
2169 Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
2170 ERR_FAIL_COND(!skeleton);
2171
2172 p_instance->update_dependency(&skeleton->dependency);
2173}
2174