From e4bfe8a80d3691a12fb915d2db75c5112f617734 Mon Sep 17 00:00:00 2001 From: Stephen Gold Date: Fri, 22 Sep 2017 09:36:52 -0700 Subject: [PATCH] testcase & fix for issue #744: collideWith() versus setIgnoreTransform() --- .../main/java/com/jme3/scene/Geometry.java | 3 + .../collision/CollideIgnoreTransformTest.java | 112 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 jme3-core/src/test/java/com/jme3/collision/CollideIgnoreTransformTest.java diff --git a/jme3-core/src/main/java/com/jme3/scene/Geometry.java b/jme3-core/src/main/java/com/jme3/scene/Geometry.java index 1e1bbcf50..9bd7ace97 100644 --- a/jme3-core/src/main/java/com/jme3/scene/Geometry.java +++ b/jme3-core/src/main/java/com/jme3/scene/Geometry.java @@ -398,6 +398,9 @@ public class Geometry extends Spatial { // Compute the cached world matrix cachedWorldMat.loadIdentity(); + if (ignoreTransform) { + return; + } cachedWorldMat.setRotationQuaternion(worldTransform.getRotation()); cachedWorldMat.setTranslation(worldTransform.getTranslation()); diff --git a/jme3-core/src/test/java/com/jme3/collision/CollideIgnoreTransformTest.java b/jme3-core/src/test/java/com/jme3/collision/CollideIgnoreTransformTest.java new file mode 100644 index 000000000..f2eb63ef8 --- /dev/null +++ b/jme3-core/src/test/java/com/jme3/collision/CollideIgnoreTransformTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.collision; + +import com.jme3.asset.AssetManager; +import com.jme3.asset.DesktopAssetManager; +import com.jme3.asset.plugins.ClasspathLocator; +import com.jme3.material.Material; +import com.jme3.material.plugins.J3MLoader; +import com.jme3.math.Ray; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Quad; +import org.junit.Test; + +/** + * Verify that collideWith() works with ignoreTransforms. This was issue #744 at + * GitHub. + * + * @author Stephen Gold + */ +public class CollideIgnoreTransformTest { + + AssetManager assetManager; + + Node rootNode; + + /** + * Cast a ray at the geometry and check the number of collisions. + */ + void castRay(Ray ray, int expectedNumResults) { + CollisionResults results = new CollisionResults(); + rootNode.collideWith(ray, results); + int numResults = results.size(); + if (numResults != expectedNumResults) { + String msg = String.format("Expected %d, got %d.", + expectedNumResults, numResults); + throw new RuntimeException(msg); + } + } + + /** + * Attach a red square in the XY plane with its lower left corner at (0, 0, + * 0). It is composed of 2 triangles. + */ + void createRedSquare() { + Mesh quadMesh = new Quad(1f, 1f); + Geometry redSquare = new Geometry("red square", quadMesh); + Material red = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + redSquare.setMaterial(red); + rootNode.attachChild(redSquare); + + redSquare.setLocalTranslation(0f, 3f, 0f); + redSquare.setIgnoreTransform(true); + } + + @Test + public void testPhantomTriangles() { + assetManager = new DesktopAssetManager(); + assetManager.registerLocator(null, ClasspathLocator.class); + assetManager.registerLoader(J3MLoader.class, "j3m", "j3md"); + rootNode = new Node(); + + createRedSquare(); + + rootNode.updateLogicalState(0.01f); + rootNode.updateGeometricState(); + /** + * ray in the -Z direction, starting from (0.5, 0.6, 10) + */ + Ray ray1 = new Ray(/* origin */new Vector3f(0.5f, 0.6f, 10f), + /* direction */ new Vector3f(0f, 0f, -1f)); + castRay(ray1, 1); + /** + * ray in the -Z direction, starting from (0.5, 3, 10) + */ + Ray ray0 = new Ray(/* origin */new Vector3f(0.5f, 3f, 10f), + /* direction */ new Vector3f(0f, 0f, -1f)); + castRay(ray0, 0); + } +}