1- package com .jme3 .scene .debug .custom ;
2-
31/*
4- * Copyright (c) 2009-2021 jMonkeyEngine
2+ * Copyright (c) 2009-2025 jMonkeyEngine
53 * All rights reserved.
64 *
75 * Redistribution and use in source and binary forms, with or without
3129 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3230 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3331 */
32+ package com .jme3 .scene .debug .custom ;
3433
3534import com .jme3 .anim .Armature ;
3635import com .jme3 .anim .Joint ;
36+ import com .jme3 .anim .SkinningControl ;
3737import com .jme3 .asset .AssetManager ;
3838import com .jme3 .collision .Collidable ;
3939import com .jme3 .collision .CollisionResults ;
5555public class ArmatureDebugger extends Node {
5656
5757 /**
58- * The lines of the bones or the wires between their heads .
58+ * The node responsible for rendering the bones/ wires and their outlines .
5959 */
6060 private ArmatureNode armatureNode ;
61-
61+ /**
62+ * The {@link Armature} instance being debugged.
63+ */
6264 private Armature armature ;
63-
65+ /**
66+ * A node containing all {@link Geometry} objects representing the joint points.
67+ */
6468 private Node joints ;
69+ /**
70+ * A node containing all {@link Geometry} objects representing the bone outlines.
71+ */
6572 private Node outlines ;
73+ /**
74+ * A node containing all {@link Geometry} objects representing the bone wires/lines.
75+ */
6676 private Node wires ;
6777 /**
6878 * The dotted lines between a bone's tail and the had of its children. Not
6979 * available if the length data was not provided.
7080 */
7181 private ArmatureInterJointsWire interJointWires ;
72-
82+ /**
83+ * Default constructor for `ArmatureDebugger`.
84+ * Use {@link #ArmatureDebugger(String, Armature, List)} for a functional instance.
85+ */
7386 public ArmatureDebugger () {
7487 }
7588
7689 /**
77- * Creates a debugger with no length data. The wires will be a connection
78- * between the bones' heads only. The points will show the bones' heads only
79- * and no dotted line of inter bones connection will be visible.
90+ * Convenience constructor that creates an {@code ArmatureDebugger} and immediately
91+ * initializes its materials based on the provided {@code AssetManager}
92+ * and {@code SkinningControl}.
93+ *
94+ * @param assetManager The {@link AssetManager} used to load textures and materials
95+ * for the debug visualization.
96+ * @param skControl The {@link SkinningControl} from which to extract the
97+ * {@link Armature} and its associated joints.
98+ */
99+ public ArmatureDebugger (AssetManager assetManager , SkinningControl skControl ) {
100+ this (null , skControl .getArmature (), skControl .getArmature ().getJointList ());
101+ initialize (assetManager , null );
102+ }
103+
104+ /**
105+ * Creates an `ArmatureDebugger` instance without explicit bone length data.
106+ * In this configuration, the visual representation will consist of wires
107+ * connecting the bone heads, and points representing the bone heads.
108+ * No dotted lines for inter-bone connections will be visible.
80109 *
81- * @param name the name of the debugger's node
82- * @param armature the armature that will be shown
83- * @param deformingJoints a list of joints
110+ * @param name The name of this debugger's root node.
111+ * @param armature The {@link Armature} to be visualized.
112+ * @param deformingJoints A {@link List} of {@link Joint} objects that are
113+ * considered deforming joints.
84114 */
85115 public ArmatureDebugger (String name , Armature armature , List <Joint > deformingJoints ) {
86116 super (name );
87117 this .armature = armature ;
118+ // Ensure the armature's world transforms are up-to-date before visualization.
88119 armature .update ();
89120
121+ // Initialize the main container nodes for different visual elements.
90122 joints = new Node ("joints" );
91123 outlines = new Node ("outlines" );
92124 wires = new Node ("bones" );
93125 this .attachChild (joints );
94126 this .attachChild (outlines );
95127 this .attachChild (wires );
96- Node ndJoints = new Node ("non deforming Joints" );
97- Node ndOutlines = new Node ("non deforming Joints outlines" );
98- Node ndWires = new Node ("non deforming Joints wires" );
99- joints .attachChild (ndJoints );
100- outlines .attachChild (ndOutlines );
101- wires .attachChild (ndWires );
102- Node outlineDashed = new Node ("Outlines Dashed" );
103- Node wiresDashed = new Node ("Wires Dashed" );
104- wiresDashed .attachChild (new Node ("dashed non defrom" ));
105- outlineDashed .attachChild (new Node ("dashed non defrom" ));
128+
129+ // Create child nodes specifically for non-deforming joints' visualization
130+ joints .attachChild (new Node ("NonDeformingJoints" ));
131+ outlines .attachChild (new Node ("NonDeformingOutlines" ));
132+ wires .attachChild (new Node ("NonDeformingWires" ));
133+
134+ Node outlineDashed = new Node ("DashedOutlines" );
135+ outlineDashed .attachChild (new Node ("DashedNonDeformingOutlines" ));
106136 outlines .attachChild (outlineDashed );
137+
138+ Node wiresDashed = new Node ("DashedWires" );
139+ wiresDashed .attachChild (new Node ("DashedNonDeformingWires" ));
107140 wires .attachChild (wiresDashed );
108141
142+ // Initialize the core ArmatureNode which handles the actual mesh generation.
109143 armatureNode = new ArmatureNode (armature , joints , wires , outlines , deformingJoints );
110-
111144 this .attachChild (armatureNode );
112145
146+ // By default, non-deforming joints are hidden.
113147 displayNonDeformingJoint (false );
114148 }
115149
150+ /**
151+ * Sets the visibility of non-deforming joints and their associated outlines and wires.
152+ *
153+ * @param display `true` to make non-deforming joints visible, `false` to hide them.
154+ */
116155 public void displayNonDeformingJoint (boolean display ) {
117- joints .getChild (0 ).setCullHint (display ? CullHint .Dynamic : CullHint .Always );
118- outlines .getChild (0 ).setCullHint (display ? CullHint .Dynamic : CullHint .Always );
119- wires .getChild (0 ).setCullHint (display ? CullHint .Dynamic : CullHint .Always );
120- ((Node ) outlines .getChild (1 )).getChild (0 ).setCullHint (display ? CullHint .Dynamic : CullHint .Always );
121- ((Node ) wires .getChild (1 )).getChild (0 ).setCullHint (display ? CullHint .Dynamic : CullHint .Always );
156+ CullHint cullHint = display ? CullHint .Dynamic : CullHint .Always ;
157+
158+ joints .getChild (0 ).setCullHint (cullHint );
159+ outlines .getChild (0 ).setCullHint (cullHint );
160+ wires .getChild (0 ).setCullHint (cullHint );
161+
162+ ((Node ) outlines .getChild (1 )).getChild (0 ).setCullHint (cullHint );
163+ ((Node ) wires .getChild (1 )).getChild (0 ).setCullHint (cullHint );
122164 }
123165
166+ /**
167+ * Initializes the materials and camera for the debugger's visual components.
168+ * This method should be called after the `ArmatureDebugger` is added to a scene graph
169+ * and an {@link AssetManager} and {@link Camera} are available.
170+ *
171+ * @param assetManager The {@link AssetManager} to load textures and materials.
172+ * @param camera The scene's primary {@link Camera}, used by the `ArmatureNode`
173+ * for billboard rendering of joint points.
174+ */
124175 public void initialize (AssetManager assetManager , Camera camera ) {
125176
126177 armatureNode .setCamera (camera );
127178
128- Material matJoints = new Material (assetManager , "Common/MatDefs/Misc/Billboard.j3md" );
129- Texture t = assetManager .loadTexture ("Common/Textures/dot.png" );
130- matJoints .setTexture ("Texture" , t );
131- matJoints .getAdditionalRenderState ().setDepthTest (false );
132- matJoints .getAdditionalRenderState ().setBlendMode (RenderState .BlendMode .Alpha );
179+ // Material for joint points (billboard dots).
180+ Material matJoints = getJointMaterial (assetManager );
133181 joints .setQueueBucket (RenderQueue .Bucket .Translucent );
134182 joints .setMaterial (matJoints );
135183
136- Material matWires = new Material (assetManager , "Common/MatDefs/Misc/Unshaded.j3md" );
137- matWires .setBoolean ("VertexColor" , true );
138- matWires .getAdditionalRenderState ().setLineWidth (1f );
184+ // Material for bone wires/lines (unshaded, vertex colored).
185+ Material matWires = getUnshadedMaterial (assetManager );
139186 wires .setMaterial (matWires );
140187
141- Material matOutline = new Material (assetManager , "Common/MatDefs/Misc/Unshaded.j3md" );
142- matOutline .setBoolean ("VertexColor" , true );
143- matOutline .getAdditionalRenderState ().setLineWidth (1f );
188+ // Material for dashed wires ("DashedLine.j3md" shader).
189+ Material matWires2 = getDashedMaterial (assetManager );
190+ wires .getChild (1 ).setMaterial (matWires2 );
191+
192+ // Material for bone outlines (unshaded, vertex colored).
193+ Material matOutline = getUnshadedMaterial (assetManager );
144194 outlines .setMaterial (matOutline );
145195
146- Material matOutline2 = new Material ( assetManager , "Common/MatDefs/Misc/ DashedLine.j3md");
147- matOutline2 . getAdditionalRenderState (). setLineWidth ( 1 );
196+ // Material for dashed outlines (" DashedLine.j3md" shader).
197+ Material matOutline2 = getDashedMaterial ( assetManager );
148198 outlines .getChild (1 ).setMaterial (matOutline2 );
199+ }
149200
150- Material matWires2 = new Material (assetManager , "Common/MatDefs/Misc/DashedLine.j3md" );
151- matWires2 .getAdditionalRenderState ().setLineWidth (1 );
152- wires .getChild (1 ).setMaterial (matWires2 );
201+ private Material getJointMaterial (AssetManager asm ) {
202+ Material mat = new Material (asm , "Common/MatDefs/Misc/Billboard.j3md" );
203+ Texture tex = asm .loadTexture ("Common/Textures/dot.png" );
204+ mat .setTexture ("Texture" , tex );
205+ mat .getAdditionalRenderState ().setDepthTest (false );
206+ mat .getAdditionalRenderState ().setBlendMode (RenderState .BlendMode .Alpha );
207+ return mat ;
208+ }
209+
210+ private Material getUnshadedMaterial (AssetManager asm ) {
211+ Material mat = new Material (asm , "Common/MatDefs/Misc/Unshaded.j3md" );
212+ mat .setBoolean ("VertexColor" , true );
213+ mat .getAdditionalRenderState ().setDepthTest (false );
214+ return mat ;
215+ }
153216
217+ private Material getDashedMaterial (AssetManager asm ) {
218+ Material mat = new Material (asm , "Common/MatDefs/Misc/DashedLine.j3md" );
219+ mat .getAdditionalRenderState ().setDepthTest (false );
220+ return mat ;
154221 }
155222
223+ /**
224+ * Returns the {@link Armature} instance associated with this debugger.
225+ *
226+ * @return The {@link Armature} being debugged.
227+ */
156228 public Armature getArmature () {
157229 return armature ;
158230 }
@@ -168,21 +240,35 @@ public int collideWith(Collidable other, CollisionResults results) {
168240 return armatureNode .collideWith (other , results );
169241 }
170242
171- protected Joint select (Geometry g ) {
172- return armatureNode .select (g );
243+ /**
244+ * Selects and returns the {@link Joint} associated with a given {@link Geometry}.
245+ * This is an internal helper method, likely used for picking operations.
246+ *
247+ * @param geo The {@link Geometry} representing a part of a joint.
248+ * @return The {@link Joint} corresponding to the geometry, or `null` if not found.
249+ */
250+ protected Joint select (Geometry geo ) {
251+ return armatureNode .select (geo );
173252 }
174253
175254 /**
176- * @return the armature wires
255+ * Returns the {@link ArmatureNode} which is responsible for generating and
256+ * managing the visual mesh of the bones and wires.
257+ *
258+ * @return The {@link ArmatureNode} instance.
177259 */
178260 public ArmatureNode getBoneShapes () {
179261 return armatureNode ;
180262 }
181263
182264 /**
183- * @return the dotted line between bones (can be null)
265+ * Returns the {@link ArmatureInterJointsWire} instance, which represents the
266+ * dotted lines connecting a bone's tail to the head of its children.
267+ * This will be `null` if the debugger was created without bone length data.
268+ *
269+ * @return The {@link ArmatureInterJointsWire} instance, or `null` if not present.
184270 */
185271 public ArmatureInterJointsWire getInterJointWires () {
186272 return interJointWires ;
187273 }
188- }
274+ }
0 commit comments