Skip to content

Commit 166a5d7

Browse files
Copilotriccardobl
andcommitted
Revert SkeletonControl changes - keep bounds update only in SkinningControl
Agent-Logs-Url: https://github.com/jMonkeyEngine/jmonkeyengine/sessions/87b0376a-f5e4-4caf-bab1-6bb85e219ddf Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com>
1 parent f4661dc commit 166a5d7

1 file changed

Lines changed: 0 additions & 155 deletions

File tree

jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java

Lines changed: 0 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
package com.jme3.animation;
3333

3434
import com.jme3.anim.SkinningControl;
35-
import com.jme3.bounding.BoundingBox;
36-
import com.jme3.bounding.BoundingVolume;
3735
import com.jme3.export.*;
3836
import com.jme3.material.MatParamOverride;
3937
import com.jme3.math.FastMath;
@@ -108,13 +106,6 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl
108106
*/
109107
private transient Matrix4f[] offsetMatrices;
110108

111-
/**
112-
* When true, the bounding volumes of animated geometries are updated each
113-
* frame to match the current pose, ensuring correct frustum culling.
114-
* Disabled by default because it adds CPU cost every frame.
115-
*/
116-
private boolean updateBounds = false;
117-
118109
private MatParamOverride numberOfBonesParam;
119110
private MatParamOverride boneMatricesParam;
120111

@@ -200,32 +191,6 @@ public boolean isHardwareSkinningUsed() {
200191
return hwSkinningEnabled;
201192
}
202193

203-
/**
204-
* Enables or disables per-frame bounding-volume updates for animated
205-
* geometries. When enabled, the bounding volume of each deformed geometry
206-
* is recomputed every render frame to match the current animation pose,
207-
* ensuring correct frustum culling at the cost of additional CPU work.
208-
* Disabled by default.
209-
*
210-
* @param updateBounds true to update bounds each frame, false to keep
211-
* static bind-pose bounds (default=false)
212-
* @see #isUpdateBounds()
213-
*/
214-
public void setUpdateBounds(boolean updateBounds) {
215-
this.updateBounds = updateBounds;
216-
}
217-
218-
/**
219-
* Returns whether per-frame bounding-volume updates are enabled for
220-
* animated geometries.
221-
*
222-
* @return true if bounds are updated each frame, false otherwise
223-
* @see #setUpdateBounds(boolean)
224-
*/
225-
public boolean isUpdateBounds() {
226-
return updateBounds;
227-
}
228-
229194
/**
230195
* Creates a skeleton control. The list of targets will be acquired
231196
* automatically when the control is attached to a node.
@@ -294,28 +259,12 @@ private void controlRenderSoftware() {
294259
// already ensured this mesh is animated.
295260
// Otherwise a crash will happen in skin update.
296261
softwareSkinUpdate(mesh, offsetMatrices);
297-
if (updateBounds) {
298-
// Update the mesh bounding volume to reflect the animated vertex positions.
299-
geometry.updateModelBound();
300-
}
301262
}
302263
}
303264

304265
private void controlRenderHardware() {
305266
offsetMatrices = skeleton.computeSkinningMatrices();
306267
boneMatricesParam.setValue(offsetMatrices);
307-
308-
if (updateBounds) {
309-
// Hardware skinning transforms vertices on the GPU, so the CPU-side vertex
310-
// buffer is not updated. Compute the animated bounding volume from the bind
311-
// pose positions and the current skinning matrices so culling is correct.
312-
for (Geometry geometry : targets) {
313-
Mesh mesh = geometry.getMesh();
314-
if (mesh != null && mesh.isAnimated()) {
315-
updateSkinnedMeshBound(geometry, mesh, offsetMatrices);
316-
}
317-
}
318-
}
319268
}
320269

321270
@Override
@@ -754,108 +703,6 @@ private void applySkinningTangents(Mesh mesh, Matrix4f[] offsetMatrices, VertexB
754703
tb.updateData(ftb);
755704
}
756705

757-
/**
758-
* Computes the bounding volume of an animated mesh from the bind pose
759-
* positions and the current skinning matrices, then sets it on the geometry.
760-
* This is used during hardware skinning to keep culling correct, since the
761-
* GPU-transformed vertex positions are not reflected in the CPU-side vertex
762-
* buffer.
763-
*
764-
* @param geometry the geometry whose bound needs to be updated
765-
* @param mesh the animated mesh
766-
* @param offsetMatrices the bone offset matrices for this frame
767-
*/
768-
private static void updateSkinnedMeshBound(Geometry geometry, Mesh mesh,
769-
Matrix4f[] offsetMatrices) {
770-
VertexBuffer bindPosVB = mesh.getBuffer(Type.BindPosePosition);
771-
if (bindPosVB == null) {
772-
return;
773-
}
774-
VertexBuffer boneIndexVB = mesh.getBuffer(Type.BoneIndex);
775-
VertexBuffer boneWeightVB = mesh.getBuffer(Type.BoneWeight);
776-
if (boneIndexVB == null || boneWeightVB == null) {
777-
return;
778-
}
779-
int maxWeightsPerVert = mesh.getMaxNumWeights();
780-
if (maxWeightsPerVert <= 0) {
781-
return;
782-
}
783-
int fourMinusMaxWeights = 4 - maxWeightsPerVert;
784-
785-
FloatBuffer bindPos = (FloatBuffer) bindPosVB.getData();
786-
bindPos.rewind();
787-
IndexBuffer boneIndex = IndexBuffer.wrapIndexBuffer(boneIndexVB.getData());
788-
FloatBuffer boneWeightBuf = (FloatBuffer) boneWeightVB.getData();
789-
boneWeightBuf.rewind();
790-
// Use array() when available (heap buffer), otherwise copy to a local array.
791-
float[] weights;
792-
if (boneWeightBuf.hasArray()) {
793-
weights = boneWeightBuf.array();
794-
} else {
795-
weights = new float[boneWeightBuf.limit()];
796-
boneWeightBuf.get(weights);
797-
}
798-
int idxWeights = 0;
799-
800-
int numVerts = bindPos.limit() / 3;
801-
float minX = Float.POSITIVE_INFINITY, minY = Float.POSITIVE_INFINITY,
802-
minZ = Float.POSITIVE_INFINITY;
803-
float maxX = Float.NEGATIVE_INFINITY, maxY = Float.NEGATIVE_INFINITY,
804-
maxZ = Float.NEGATIVE_INFINITY;
805-
806-
for (int v = 0; v < numVerts; v++) {
807-
float vtx = bindPos.get();
808-
float vty = bindPos.get();
809-
float vtz = bindPos.get();
810-
811-
float rx, ry, rz;
812-
if (weights[idxWeights] == 0) {
813-
idxWeights += 4;
814-
rx = vtx;
815-
ry = vty;
816-
rz = vtz;
817-
} else {
818-
rx = 0;
819-
ry = 0;
820-
rz = 0;
821-
for (int w = 0; w < maxWeightsPerVert; w++) {
822-
float weight = weights[idxWeights];
823-
Matrix4f mat = offsetMatrices[boneIndex.get(idxWeights++)];
824-
rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
825-
ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
826-
rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;
827-
}
828-
idxWeights += fourMinusMaxWeights;
829-
}
830-
831-
if (rx < minX) minX = rx;
832-
if (rx > maxX) maxX = rx;
833-
if (ry < minY) minY = ry;
834-
if (ry > maxY) maxY = ry;
835-
if (rz < minZ) minZ = rz;
836-
if (rz > maxZ) maxZ = rz;
837-
}
838-
839-
// Reuse the existing BoundingBox if possible to avoid allocation.
840-
BoundingVolume bv = mesh.getBound();
841-
BoundingBox bbox;
842-
if (bv instanceof BoundingBox) {
843-
bbox = (BoundingBox) bv;
844-
} else {
845-
bbox = new BoundingBox();
846-
}
847-
TempVars vars = TempVars.get();
848-
try {
849-
vars.vect1.set(minX, minY, minZ);
850-
vars.vect2.set(maxX, maxY, maxZ);
851-
bbox.setMinMax(vars.vect1, vars.vect2);
852-
} finally {
853-
vars.release();
854-
}
855-
// setModelBound() updates the mesh bound and triggers a world-bound refresh.
856-
geometry.setModelBound(bbox);
857-
}
858-
859706
@Override
860707
public void write(JmeExporter ex) throws IOException {
861708
super.write(ex);
@@ -864,7 +711,6 @@ public void write(JmeExporter ex) throws IOException {
864711

865712
oc.write(numberOfBonesParam, "numberOfBonesParam", null);
866713
oc.write(boneMatricesParam, "boneMatricesParam", null);
867-
oc.write(updateBounds, "updateBounds", false);
868714
}
869715

870716
@Override
@@ -875,7 +721,6 @@ public void read(JmeImporter im) throws IOException {
875721

876722
numberOfBonesParam = (MatParamOverride) in.readSavable("numberOfBonesParam", null);
877723
boneMatricesParam = (MatParamOverride) in.readSavable("boneMatricesParam", null);
878-
updateBounds = in.readBoolean("updateBounds", false);
879724

880725
if (numberOfBonesParam == null) {
881726
numberOfBonesParam = new MatParamOverride(VarType.Int, "NumberOfBones", null);

0 commit comments

Comments
 (0)