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