Login  Register

Re: Collision Detection Bug in Java 3D 1.5.2

Posted by Christian on Oct 15, 2015; 1:43pm
URL: https://forum.jogamp.org/Collision-Detection-Bug-in-Java-3D-1-5-2-tp4035467p4035471.html

Dear gouessej,

Thank you for your answer. I tried it with Java3d 1.6.0 pre12 and the error still appears.

I wrote a example program, where the problem is reproducible.

package com.example.coll;

import java.util.Enumeration;

import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.DirectionalLight;

import javax.media.j3d.Node;

import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnCollisionEntry;
import javax.media.j3d.WakeupOnCollisionExit;
import javax.media.j3d.WakeupOnCollisionMovement;
import javax.media.j3d.WakeupOr;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;

import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;


import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class CollisionBugExample {

        public CollisionBugExample() {
                SimpleUniverse universe = new SimpleUniverse();
                BranchGroup group = new BranchGroup();

                FixedSphere shape1 = new FixedSphere(0.3f);
                group.addChild(shape1.getSphereTGrp());
                shape1.setPosition(new Vector3d(+0.2, 0.0, 0.0));
           
                FixedSphere shape2 = new FixedSphere(0.3f);
                group.addChild(shape2.getSphereTGrp());
                shape2.setPosition(new Vector3d(-0.2, 0.0, 0.0));
           
                MovingSphere shape3 = new MovingSphere(0.1f);
                group.addChild(shape3.getSphereTGrp());
                group.addChild(shape3);

                Color3f light1Color = new Color3f(1.8f, 0.1f, 0.1f);
                BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
                Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
                DirectionalLight light1 = new DirectionalLight(light1Color, light1Direction);
                light1.setInfluencingBounds(bounds);
                group.addChild(light1);

                universe.getViewingPlatform().setNominalViewingTransform();
                universe.addBranchGraph(group);
           
                // move the moving sphere
           
                for(double i = 1.0; i > -1.0; i -= 0.01) {
                        shape3.setPosition(new Vector3d(i, 0.0, 0.0));
                        try {
                                Thread.sleep(100);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }

        public static void main(String[] args) {
                new CollisionBugExample();
        }
}

class FixedSphere {
       
        private Sphere sphere;
       
        private TransformGroup transGrp;
       
        public FixedSphere(float size) {
                transGrp = new TransformGroup();
                sphere = new Sphere(size);
                transGrp.addChild(sphere);
        }

        public TransformGroup getSphereTGrp() {
                return transGrp;
        }
       
        public void setPosition(Vector3d position) {
                Transform3D transform = new Transform3D();
                transform.setTranslation(position);
                transGrp.setTransform(transform);
        }
}

class MovingSphere extends Behavior {
       
        private Sphere sphere;
       
        private TransformGroup transGrp;
       
        private WakeupCriterion[] collisionCriteria;
        private WakeupOr oredCriteria;
       
        public MovingSphere(float size) {
                transGrp = new TransformGroup();
                transGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
                sphere = new Sphere(size);
                transGrp.addChild(sphere);
               
                setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0));
        }

        public TransformGroup getSphereTGrp() {
                return transGrp;
        }
       
        public void setPosition(Vector3d position) {
                Transform3D transform = new Transform3D();
                transform.setTranslation(position);
                transGrp.setTransform(transform);
        }

        @Override
        public void initialize() {
                collisionCriteria = new WakeupCriterion[3];
                collisionCriteria[0] = new WakeupOnCollisionEntry(sphere);
                collisionCriteria[1] = new WakeupOnCollisionExit(sphere);
                collisionCriteria[2] = new WakeupOnCollisionMovement(sphere);
                oredCriteria = new WakeupOr(collisionCriteria);
                wakeupOn(oredCriteria);
        }

        @Override
        public void processStimulus(Enumeration criteria) {
                WakeupCriterion theCriterion = (WakeupCriterion) criteria.nextElement();
                Node collisionShape;

                if(theCriterion instanceof WakeupOnCollisionEntry) {
                        collisionShape = ((WakeupOnCollisionEntry) theCriterion).getTriggeringPath().getObject();
                } else if(theCriterion instanceof WakeupOnCollisionExit) {
                        collisionShape = ((WakeupOnCollisionExit) theCriterion).getTriggeringPath().getObject();
                } else {
                        collisionShape = ((WakeupOnCollisionMovement) theCriterion).getTriggeringPath().getObject();
                }
               
                System.out.println(theCriterion + " : collide with " + collisionShape);
               
                wakeupOn(oredCriteria);
        }
}

With this example you can see, that the collision bounds of the fixed spheres intersect and that a collision between the moved sphere and shape1 occurs, but no detection with the collision bounds of shape2 occurs. But it should with sphere2 as well.

If you change the position of fixed spheres to...
                FixedSphere shape1 = new FixedSphere(0.3f);
                group.addChild(shape1.getSphereTGrp());
                shape1.setPosition(new Vector3d(+0.5, 0.0, 0.0));
           
                FixedSphere shape2 = new FixedSphere(0.3f);
                group.addChild(shape2.getSphereTGrp());
                shape2.setPosition(new Vector3d(-0.5, 0.0, 0.0));
           
... the collision bounds don't intersect and everything is fine.

Christian