Skip to content

Commit 07da12c

Browse files
committed
updated applying scale to physics and to box shapes.
1 parent 941c4d0 commit 07da12c

File tree

7 files changed

+243
-66
lines changed

7 files changed

+243
-66
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright (c) 2009-2017 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.bullet.util;
33+
34+
import com.jme3.bullet.collision.shapes.CollisionShape;
35+
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
36+
import com.jme3.bullet.collision.shapes.infos.ChildCollisionShape;
37+
import com.jme3.math.Matrix3f;
38+
import com.jme3.math.Vector3f;
39+
import com.jme3.scene.Geometry;
40+
import com.jme3.scene.Mesh;
41+
import com.jme3.scene.Node;
42+
import com.jme3.scene.Spatial;
43+
import com.jme3.scene.VertexBuffer.Type;
44+
import com.jme3.util.TempVars;
45+
import java.util.Iterator;
46+
import java.util.List;
47+
48+
/**
49+
*
50+
* @author CJ Hare, normenhansen
51+
*/
52+
public class DebugShapeFactory {
53+
54+
/** The maximum corner for the aabb used for triangles to include in ConcaveShape processing.*/
55+
// private static final Vector3f aabbMax = new Vector3f(1e30f, 1e30f, 1e30f);
56+
/** The minimum corner for the aabb used for triangles to include in ConcaveShape processing.*/
57+
// private static final Vector3f aabbMin = new Vector3f(-1e30f, -1e30f, -1e30f);
58+
59+
/**
60+
* Creates a debug shape from the given collision shape. This is mostly used internally.<br>
61+
* To attach a debug shape to a physics object, call <code>attachDebugShape(AssetManager manager);</code> on it.
62+
* @param collisionShape
63+
* @return
64+
*/
65+
public static Spatial getDebugShape(CollisionShape collisionShape) {
66+
if (collisionShape == null) {
67+
return null;
68+
}
69+
Spatial debugShape;
70+
if (collisionShape instanceof CompoundCollisionShape) {
71+
CompoundCollisionShape shape = (CompoundCollisionShape) collisionShape;
72+
List<ChildCollisionShape> children = shape.getChildren();
73+
Node node = new Node("DebugShapeNode");
74+
for (Iterator<ChildCollisionShape> it = children.iterator(); it.hasNext();) {
75+
ChildCollisionShape childCollisionShape = it.next();
76+
CollisionShape ccollisionShape = childCollisionShape.shape;
77+
Geometry geometry = createDebugShape(ccollisionShape);
78+
79+
// apply translation
80+
geometry.setLocalTranslation(childCollisionShape.location);
81+
82+
// apply rotation
83+
TempVars vars = TempVars.get();
84+
Matrix3f tempRot = vars.tempMat3;
85+
86+
tempRot.set(geometry.getLocalRotation());
87+
childCollisionShape.rotation.mult(tempRot, tempRot);
88+
geometry.setLocalRotation(tempRot);
89+
geometry.setLocalScale(ccollisionShape.getScale());
90+
91+
vars.release();
92+
93+
node.attachChild(geometry);
94+
}
95+
debugShape = node;
96+
} else {
97+
debugShape = createDebugShape(collisionShape);
98+
}
99+
if (debugShape == null) {
100+
return null;
101+
}
102+
debugShape.updateGeometricState();
103+
return debugShape;
104+
}
105+
106+
private static Geometry createDebugShape(CollisionShape shape) {
107+
Geometry geom = new Geometry();
108+
geom.setMesh(DebugShapeFactory.getDebugMesh(shape));
109+
// geom.setLocalScale(shape.getScale());
110+
geom.updateModelBound();
111+
return geom;
112+
}
113+
114+
public static Mesh getDebugMesh(CollisionShape shape) {
115+
Mesh mesh = new Mesh();
116+
DebugMeshCallback callback = new DebugMeshCallback();
117+
/*
118+
* Populate the mesh based on an unscaled shape;
119+
* the shape's scale will be applied later, to the geometry.
120+
*/
121+
Vector3f savedScale = shape.getScale().clone();
122+
shape.setScale(Vector3f.UNIT_XYZ);
123+
getVertices(shape.getObjectId(), callback);
124+
shape.setScale(savedScale);
125+
126+
mesh.setBuffer(Type.Position, 3, callback.getVertices());
127+
mesh.getFloatBuffer(Type.Position).clear();
128+
return mesh;
129+
}
130+
131+
private static native void getVertices(long shapeId, DebugMeshCallback buffer);
132+
}

src/main/java/com/ss/editor/part3d/editor/impl/scene/AbstractSceneEditor3DPart.java

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import static com.ss.editor.util.NodeUtils.findParent;
44
import static com.ss.rlib.util.ObjectUtils.notNull;
5-
import static java.util.stream.Collectors.toMap;
6-
75
import com.jme3.app.state.AppState;
86
import com.jme3.asset.AssetManager;
97
import com.jme3.asset.AssetNotFoundException;
@@ -82,6 +80,7 @@ public abstract class AbstractSceneEditor3DPart<T extends AbstractSceneFileEdito
8280
public static final String KEY_IGNORE_RAY_CAST = "jMB.sceneEditor.ignoreRayCast";
8381
public static final String KEY_MODEL_NODE = "jMB.sceneEditor.modelNode";
8482
public static final String KEY_SHAPE_CENTER = "jMB.sceneEditor.shapeCenter";
83+
public static final String KEY_SHAPE_INIT_SCALE = "jMB.sceneEditor.initScale";
8584

8685
private static final String KEY_S = "SSEditor.sceneEditorState.S";
8786
private static final String KEY_G = "SSEditor.sceneEditorState.G";
@@ -211,7 +210,7 @@ public static void registerPostTransformHandler(@NotNull final Consumer<Spatial>
211210
* The selection models of selected models.
212211
*/
213212
@NotNull
214-
private final ObjectDictionary<Spatial, Spatial> selectionShape;
213+
private final ObjectDictionary<Spatial, Geometry> selectionShape;
215214

216215
/**
217216
* The array of selected models.
@@ -873,8 +872,8 @@ protected void postCameraUpdate(final float tpf) {
873872

874873
state.updateTransformNode(spatial.getWorldTransform());
875874

876-
final ObjectDictionary<Spatial, Spatial> selectionShape = state.getSelectionShape();
877-
final Spatial shape = selectionShape.get(spatial);
875+
final ObjectDictionary<Spatial, Geometry> selectionShape = state.getSelectionShape();
876+
final Geometry shape = selectionShape.get(spatial);
878877
if (shape == null) {
879878
return;
880879
}
@@ -883,13 +882,31 @@ protected void postCameraUpdate(final float tpf) {
883882
position.set(spatial.getWorldTranslation());
884883

885884
final Vector3f center = shape.getUserData(KEY_SHAPE_CENTER);
885+
final Vector3f initScale = shape.getUserData(KEY_SHAPE_INIT_SCALE);
886886

887887
if (center != null) {
888+
889+
if (!initScale.equals(spatial.getLocalScale())) {
890+
891+
initScale.set(spatial.getLocalScale());
892+
893+
NodeUtils.updateWorldBound(spatial);
894+
895+
final BoundingBox bound = (BoundingBox) spatial.getWorldBound();
896+
bound.getCenter().subtract(spatial.getWorldTranslation(), center);
897+
898+
final WireBox mesh = (WireBox) shape.getMesh();
899+
mesh.updatePositions(bound.getXExtent(), bound.getYExtent(), bound.getZExtent());
900+
}
901+
888902
position.addLocal(center);
903+
904+
} else {
905+
shape.setLocalRotation(spatial.getWorldRotation());
906+
shape.setLocalScale(spatial.getWorldScale());
889907
}
890908

891909
shape.setLocalTranslation(position);
892-
shape.setLocalRotation(spatial.getWorldRotation());
893910
});
894911

895912
transformToolNode.detachAllChildren();
@@ -1028,7 +1045,7 @@ private void updateTransformNode(@Nullable final Transform transform) {
10281045
* @return the selection models of selected models.
10291046
*/
10301047
@FromAnyThread
1031-
private @NotNull ObjectDictionary<Spatial, Spatial> getSelectionShape() {
1048+
private @NotNull ObjectDictionary<Spatial, Geometry> getSelectionShape() {
10321049
return selectionShape;
10331050
}
10341051

@@ -1213,7 +1230,7 @@ private void addToSelection(@NotNull final Spatial spatial) {
12131230
return;
12141231
}
12151232

1216-
Spatial shape;
1233+
Geometry shape;
12171234

12181235
if (spatial instanceof ParticleEmitter) {
12191236
shape = buildBoxSelection(spatial);
@@ -1232,7 +1249,7 @@ private void addToSelection(@NotNull final Spatial spatial) {
12321249
toolNode.attachChild(shape);
12331250
}
12341251

1235-
final ObjectDictionary<Spatial, Spatial> selectionShape = getSelectionShape();
1252+
final ObjectDictionary<Spatial, Geometry> selectionShape = getSelectionShape();
12361253
selectionShape.put(spatial, shape);
12371254
}
12381255

@@ -1244,7 +1261,7 @@ private void removeFromSelection(@NotNull final Spatial spatial) {
12441261
setTransformCenter(null);
12451262
setToTransform(null);
12461263

1247-
final ObjectDictionary<Spatial, Spatial> selectionShape = getSelectionShape();
1264+
final ObjectDictionary<Spatial, Geometry> selectionShape = getSelectionShape();
12481265

12491266
final Spatial shape = selectionShape.remove(spatial);
12501267
if (shape != null) {
@@ -1260,7 +1277,7 @@ private void removeFromSelection(@NotNull final Spatial spatial) {
12601277
* Build the selection box for the spatial.
12611278
*/
12621279
@JmeThread
1263-
private Spatial buildBoxSelection(@NotNull final Spatial spatial) {
1280+
private Geometry buildBoxSelection(@NotNull final Spatial spatial) {
12641281
NodeUtils.updateWorldBound(spatial);
12651282

12661283
final BoundingVolume bound = spatial.getWorldBound();
@@ -1269,11 +1286,13 @@ private Spatial buildBoxSelection(@NotNull final Spatial spatial) {
12691286

12701287
final BoundingBox boundingBox = (BoundingBox) bound;
12711288
final Vector3f center = boundingBox.getCenter().subtract(spatial.getWorldTranslation());
1289+
final Vector3f initScale = spatial.getLocalScale().clone();
12721290

12731291
final Geometry geometry = WireBox.makeGeometry(boundingBox);
12741292
geometry.setName("SelectionShape");
12751293
geometry.setMaterial(getSelectionMaterial());
12761294
geometry.setUserData(KEY_SHAPE_CENTER, center);
1295+
geometry.setUserData(KEY_SHAPE_INIT_SCALE, initScale);
12771296

12781297
final Vector3f position = geometry.getLocalTranslation();
12791298
position.addLocal(center);
@@ -1308,10 +1327,12 @@ private Spatial buildBoxSelection(@NotNull final Spatial spatial) {
13081327
* Build selection grid for the geometry.
13091328
*/
13101329
@JmeThread
1311-
private Spatial buildGeometrySelection(@NotNull final Geometry geom) {
1330+
private Geometry buildGeometrySelection(@NotNull final Geometry geom) {
13121331

13131332
final Mesh mesh = geom.getMesh();
1314-
if (mesh == null) return null;
1333+
if (mesh == null) {
1334+
return null;
1335+
}
13151336

13161337
final Geometry geometry = new Geometry("SelectionShape", mesh);
13171338
geometry.setMaterial(getSelectionMaterial());
@@ -1380,7 +1401,7 @@ private void updateShowSelectionImpl(final boolean showSelection) {
13801401
return;
13811402
}
13821403

1383-
final ObjectDictionary<Spatial, Spatial> selectionShape = getSelectionShape();
1404+
final ObjectDictionary<Spatial, Geometry> selectionShape = getSelectionShape();
13841405
final Node toolNode = getToolNode();
13851406

13861407
if (showSelection && !selectionShape.isEmpty()) {

0 commit comments

Comments
 (0)