30
30
31
31
#include " csg_shape.h"
32
32
33
+ #ifdef DEV_ENABLED
34
+ #include " core/io/json.h"
35
+ #endif // DEV_ENABLED
33
36
#include " core/math/geometry_2d.h"
34
37
35
38
#include < manifold/manifold.h>
@@ -142,6 +145,7 @@ bool CSGShape3D::is_root_shape() const {
142
145
return !parent_shape;
143
146
}
144
147
148
+ #ifndef DISABLE_DEPRECATED
145
149
void CSGShape3D::set_snap (float p_snap) {
146
150
if (snap == p_snap) {
147
151
return ;
@@ -154,6 +158,7 @@ void CSGShape3D::set_snap(float p_snap) {
154
158
float CSGShape3D::get_snap () const {
155
159
return snap;
156
160
}
161
+ #endif // DISABLE_DEPRECATED
157
162
158
163
void CSGShape3D::_make_dirty (bool p_parent_removing) {
159
164
if ((p_parent_removing || is_root_shape ()) && !dirty) {
@@ -232,21 +237,118 @@ static void _unpack_manifold(
232
237
r_mesh_merge->_regen_face_aabbs ();
233
238
}
234
239
240
+ // Errors matching `thirdparty/manifold/include/manifold/manifold.h`.
241
+ static String manifold_error_to_string (const manifold::Manifold::Error &p_error) {
242
+ switch (p_error) {
243
+ case manifold::Manifold::Error::NoError:
244
+ return " No Error" ;
245
+ case manifold::Manifold::Error::NonFiniteVertex:
246
+ return " Non Finite Vertex" ;
247
+ case manifold::Manifold::Error::NotManifold:
248
+ return " Not Manifold" ;
249
+ case manifold::Manifold::Error::VertexOutOfBounds:
250
+ return " Vertex Out Of Bounds" ;
251
+ case manifold::Manifold::Error::PropertiesWrongLength:
252
+ return " Properties Wrong Length" ;
253
+ case manifold::Manifold::Error::MissingPositionProperties:
254
+ return " Missing Position Properties" ;
255
+ case manifold::Manifold::Error::MergeVectorsDifferentLengths:
256
+ return " Merge Vectors Different Lengths" ;
257
+ case manifold::Manifold::Error::MergeIndexOutOfBounds:
258
+ return " Merge Index Out Of Bounds" ;
259
+ case manifold::Manifold::Error::TransformWrongLength:
260
+ return " Transform Wrong Length" ;
261
+ case manifold::Manifold::Error::RunIndexWrongLength:
262
+ return " Run Index Wrong Length" ;
263
+ case manifold::Manifold::Error::FaceIDWrongLength:
264
+ return " Face ID Wrong Length" ;
265
+ case manifold::Manifold::Error::InvalidConstruction:
266
+ return " Invalid Construction" ;
267
+ default :
268
+ return " Unknown Error" ;
269
+ }
270
+ }
271
+
272
+ #ifdef DEV_ENABLED
273
+ static String _export_meshgl_as_json (const manifold::MeshGL64 &p_mesh) {
274
+ Dictionary mesh_dict;
275
+ mesh_dict[" numProp" ] = p_mesh.numProp ;
276
+
277
+ Array vert_properties;
278
+ for (const double &val : p_mesh.vertProperties ) {
279
+ vert_properties.append (val);
280
+ }
281
+ mesh_dict[" vertProperties" ] = vert_properties;
282
+
283
+ Array tri_verts;
284
+ for (const uint64_t &val : p_mesh.triVerts ) {
285
+ tri_verts.append (val);
286
+ }
287
+ mesh_dict[" triVerts" ] = tri_verts;
288
+
289
+ Array merge_from_vert;
290
+ for (const uint64_t &val : p_mesh.mergeFromVert ) {
291
+ merge_from_vert.append (val);
292
+ }
293
+ mesh_dict[" mergeFromVert" ] = merge_from_vert;
294
+
295
+ Array merge_to_vert;
296
+ for (const uint64_t &val : p_mesh.mergeToVert ) {
297
+ merge_to_vert.append (val);
298
+ }
299
+ mesh_dict[" mergeToVert" ] = merge_to_vert;
300
+
301
+ Array run_index;
302
+ for (const uint64_t &val : p_mesh.runIndex ) {
303
+ run_index.append (val);
304
+ }
305
+ mesh_dict[" runIndex" ] = run_index;
306
+
307
+ Array run_original_id;
308
+ for (const uint32_t &val : p_mesh.runOriginalID ) {
309
+ run_original_id.append (val);
310
+ }
311
+ mesh_dict[" runOriginalID" ] = run_original_id;
312
+
313
+ Array run_transform;
314
+ for (const double &val : p_mesh.runTransform ) {
315
+ run_transform.append (val);
316
+ }
317
+ mesh_dict[" runTransform" ] = run_transform;
318
+
319
+ Array face_id;
320
+ for (const uint64_t &val : p_mesh.faceID ) {
321
+ face_id.append (val);
322
+ }
323
+ mesh_dict[" faceID" ] = face_id;
324
+
325
+ Array halfedge_tangent;
326
+ for (const double &val : p_mesh.halfedgeTangent ) {
327
+ halfedge_tangent.append (val);
328
+ }
329
+ mesh_dict[" halfedgeTangent" ] = halfedge_tangent;
330
+
331
+ mesh_dict[" tolerance" ] = p_mesh.tolerance ;
332
+
333
+ String json_string = JSON::stringify (mesh_dict);
334
+ return json_string;
335
+ }
336
+ #endif // DEV_ENABLED
337
+
235
338
static void _pack_manifold (
236
339
const CSGBrush *const p_mesh_merge,
237
340
manifold::Manifold &r_manifold,
238
341
HashMap<int32_t , Ref<Material>> &p_mesh_materials,
239
- float p_snap ) {
342
+ CSGShape3D *p_csg_shape ) {
240
343
ERR_FAIL_NULL_MSG (p_mesh_merge, " p_mesh_merge is null" );
241
-
344
+ ERR_FAIL_NULL_MSG (p_csg_shape, " p_shape is null " );
242
345
HashMap<uint32_t , Vector<CSGBrush::Face>> faces_by_material;
243
346
for (int face_i = 0 ; face_i < p_mesh_merge->faces .size (); face_i++) {
244
347
const CSGBrush::Face &face = p_mesh_merge->faces [face_i];
245
348
faces_by_material[face.material ].push_back (face);
246
349
}
247
350
248
351
manifold::MeshGL64 mesh;
249
- mesh.tolerance = p_snap;
250
352
mesh.numProp = MANIFOLD_PROPERTY_MAX;
251
353
mesh.runOriginalID .reserve (faces_by_material.size ());
252
354
mesh.runIndex .reserve (faces_by_material.size () + 1 );
@@ -291,12 +393,22 @@ static void _pack_manifold(
291
393
}
292
394
// runIndex needs an explicit end value.
293
395
mesh.runIndex .push_back (mesh.triVerts .size ());
396
+ mesh.tolerance = 2 * FLT_EPSILON;
294
397
ERR_FAIL_COND_MSG (mesh.vertProperties .size () % mesh.numProp != 0 , " Invalid vertex properties size." );
295
398
mesh.Merge ();
399
+ #ifdef DEV_ENABLED
400
+ print_verbose (_export_meshgl_as_json (mesh));
401
+ #endif // DEV_ENABLED
296
402
r_manifold = manifold::Manifold (mesh);
297
- manifold::Manifold::Error err = r_manifold.Status ();
298
- if (err != manifold::Manifold::Error::NoError) {
299
- print_error (String (" Manifold creation from mesh failed:" + itos ((int )err)));
403
+ manifold::Manifold::Error error = r_manifold.Status ();
404
+ if (error == manifold::Manifold::Error::NoError) {
405
+ return ;
406
+ }
407
+ if (p_csg_shape->get_owner ()) {
408
+ NodePath path = p_csg_shape->get_owner ()->get_path_to (p_csg_shape, true );
409
+ print_error (vformat (" CSGShape3D manifold creation from mesh failed at %s: %s." , path, manifold_error_to_string (error)));
410
+ } else {
411
+ print_error (vformat (" CSGShape3D manifold creation from mesh failed at .: %s." , manifold_error_to_string (error)));
300
412
}
301
413
}
302
414
@@ -330,7 +442,7 @@ CSGBrush *CSGShape3D::_get_brush() {
330
442
CSGBrush *n = _build_brush ();
331
443
HashMap<int32_t , Ref<Material>> mesh_materials;
332
444
manifold::Manifold root_manifold;
333
- _pack_manifold (n, root_manifold, mesh_materials, get_snap () );
445
+ _pack_manifold (n, root_manifold, mesh_materials, this );
334
446
manifold::OpType current_op = ManifoldOperation::convert_csg_op (get_operation ());
335
447
std::vector<manifold::Manifold> manifolds;
336
448
manifolds.push_back (root_manifold);
@@ -346,7 +458,7 @@ CSGBrush *CSGShape3D::_get_brush() {
346
458
CSGBrush transformed_brush;
347
459
transformed_brush.copy_from (*child_brush, child->get_transform ());
348
460
manifold::Manifold child_manifold;
349
- _pack_manifold (&transformed_brush, child_manifold, mesh_materials, get_snap () );
461
+ _pack_manifold (&transformed_brush, child_manifold, mesh_materials, child );
350
462
manifold::OpType child_operation = ManifoldOperation::convert_csg_op (child->get_operation ());
351
463
if (child_operation != current_op) {
352
464
manifold::Manifold result = manifold::Manifold::BatchBoolean (manifolds, current_op);
@@ -834,8 +946,10 @@ void CSGShape3D::_bind_methods() {
834
946
ClassDB::bind_method (D_METHOD (" set_operation" , " operation" ), &CSGShape3D::set_operation);
835
947
ClassDB::bind_method (D_METHOD (" get_operation" ), &CSGShape3D::get_operation);
836
948
949
+ #ifndef DISABLE_DEPRECATED
837
950
ClassDB::bind_method (D_METHOD (" set_snap" , " snap" ), &CSGShape3D::set_snap);
838
951
ClassDB::bind_method (D_METHOD (" get_snap" ), &CSGShape3D::get_snap);
952
+ #endif // DISABLE_DEPRECATED
839
953
840
954
ClassDB::bind_method (D_METHOD (" set_use_collision" , " operation" ), &CSGShape3D::set_use_collision);
841
955
ClassDB::bind_method (D_METHOD (" is_using_collision" ), &CSGShape3D::is_using_collision);
@@ -864,7 +978,9 @@ void CSGShape3D::_bind_methods() {
864
978
ClassDB::bind_method (D_METHOD (" bake_collision_shape" ), &CSGShape3D::bake_collision_shape);
865
979
866
980
ADD_PROPERTY (PropertyInfo (Variant::INT, " operation" , PROPERTY_HINT_ENUM, " Union,Intersection,Subtraction" ), " set_operation" , " get_operation" );
867
- ADD_PROPERTY (PropertyInfo (Variant::FLOAT, " snap" , PROPERTY_HINT_RANGE, " 0.000001,1,0.000001,suffix:m" ), " set_snap" , " get_snap" );
981
+ #ifndef DISABLE_DEPRECATED
982
+ ADD_PROPERTY (PropertyInfo (Variant::FLOAT, " snap" , PROPERTY_HINT_RANGE, " 0.000001,1,0.000001,suffix:m" , PROPERTY_USAGE_NONE), " set_snap" , " get_snap" );
983
+ #endif // DISABLE_DEPRECATED
868
984
ADD_PROPERTY (PropertyInfo (Variant::BOOL, " calculate_tangents" ), " set_calculate_tangents" , " is_calculating_tangents" );
869
985
870
986
ADD_GROUP (" Collision" , " collision_" );
0 commit comments