56
56
import java .util .List ;
57
57
import java .util .logging .Logger ;
58
58
import jme3utilities .MyMesh ;
59
- import jme3utilities .MySpatial ;
60
59
import jme3utilities .Validate ;
61
60
import jme3utilities .math .MyBuffer ;
62
61
import jme3utilities .math .MyMath ;
@@ -552,28 +551,67 @@ private static MeshCollisionShape createSingleMeshShape(
552
551
}
553
552
554
553
/**
555
- * Generate a Mesh that merges the triangles of non-empty geometries not
556
- * tagged with "JmePhysicsIgnore".
554
+ * Enumerate all child geometries in the specified scene-graph subtree that
555
+ * aren't tagged with {@code UserData.JME_PHYSICSIGNORE}. Note: recursive!
557
556
*
558
- * @param subtree the scene-graph subtree on which to base the Mesh (not
559
- * null, unaffected)
557
+ * @param parent the parent of the subtree (not null, aliases created)
558
+ * @param addResult storage for results (added to if not null)
559
+ * @return a new List
560
+ */
561
+ private static List <Geometry > listUntaggedGeometries (
562
+ Node parent , List <Geometry > addResult ) {
563
+ Validate .nonNull (parent , "subtree" );
564
+ List <Geometry > result
565
+ = (addResult == null ) ? new ArrayList <>(50 ) : addResult ;
566
+
567
+ for (Spatial child : parent .getChildren ()) {
568
+ Boolean skipChild = child .getUserData (UserData .JME_PHYSICSIGNORE );
569
+ if (skipChild != null && skipChild ) {
570
+ // continue to the next child spatial
571
+
572
+ } else if (child instanceof Node ) {
573
+ listUntaggedGeometries ((Node ) child , result );
574
+
575
+ } else {
576
+ result .add ((Geometry ) child );
577
+ }
578
+ }
579
+
580
+ return result ;
581
+ }
582
+
583
+ /**
584
+ * Generate a Mesh that merges the triangles of non-empty geometries that
585
+ * aren't tagged with {@code UserData.JME_PHYSICSIGNORE}.
586
+ *
587
+ * @param modelRoot the model on which to base the shape (not null,
588
+ * unaffected)
560
589
* @return a new, indexed Mesh in Triangles mode, its bounds not set
561
590
*/
562
- private static Mesh makeMergedMesh (Spatial subtree ) {
563
- List <Geometry > allGeometries = MySpatial .listGeometries (subtree );
591
+ private static Mesh makeMergedMesh (Spatial modelRoot ) {
592
+ List <Geometry > untaggedGeometries ;
593
+ if (modelRoot instanceof Geometry ) {
594
+ /*
595
+ * To be consistent with createDynamicMeshShape() and others,
596
+ * a nodeless model isn't checked for JME_PHYSICSIGNORE.
597
+ */
598
+ untaggedGeometries = new ArrayList <Geometry >(1 );
599
+ untaggedGeometries .add ((Geometry ) modelRoot );
600
+
601
+ } else if (modelRoot instanceof Node ) {
602
+ untaggedGeometries = listUntaggedGeometries ((Node ) modelRoot , null );
603
+
604
+ } else {
605
+ throw new IllegalArgumentException (
606
+ "The model root must either be a Node or a Geometry!" );
607
+ }
608
+
564
609
Collection <Geometry > includedGeometries
565
- = new ArrayList <>(allGeometries .size ());
610
+ = new ArrayList <>(untaggedGeometries .size ());
566
611
int totalIndices = 0 ;
567
612
int totalVertices = 0 ;
568
- for (Geometry geometry : allGeometries ) {
569
- /*
570
- * Exclude any Geometry tagged with "JmePhysicsIgnore"
571
- * or having a null/empty mesh.
572
- */
573
- Boolean ignore = geometry .getUserData (UserData .JME_PHYSICSIGNORE );
574
- if (ignore != null && ignore ) {
575
- continue ;
576
- }
613
+ for (Geometry geometry : untaggedGeometries ) {
614
+ // Exclude any Geometry with a null/empty mesh.
577
615
Mesh jmeMesh = geometry .getMesh ();
578
616
if (jmeMesh == null ) {
579
617
continue ;
@@ -599,7 +637,7 @@ private static Mesh makeMergedMesh(Spatial subtree) {
599
637
FloatBuffer positionBuffer = BufferUtils .createFloatBuffer (totalFloats );
600
638
601
639
for (Geometry geometry : includedGeometries ) {
602
- appendTriangles (geometry , subtree , positionBuffer , indexBuffer );
640
+ appendTriangles (geometry , modelRoot , positionBuffer , indexBuffer );
603
641
}
604
642
605
643
VertexBuffer .Format ibFormat = indexBuffer .getFormat ();
0 commit comments