3d AABB Collision in group

Hi,

I am working on 3D AABB collisions detection for box and sphere.

If the box is directly added to scene, then i am able to get collision but if i add the box in a group, and group is rotated, then collision is not detected.

I am using this code

function addPlatforms() {

    var coreGroup = new THREE.Group();
    scene.add(coreGroup);

    plane = [];

    cube_box1 = new THREE.Box3(new THREE.Vector3(), new THREE.Vector3());
    plane.push(new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0.2), materials.solid));
    plane[0].position.set(-1.83, -0.22, 1.11);
    plane[0].rotation.x += Math.PI / 2;
    plane[0].rotation.z -= 0.78;
    plane[0].receiveShadow = true;


    cube_box2 = new THREE.Box3(new THREE.Vector3(), new THREE.Vector3());
    plane.push(new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0.2), materials.solid));
    plane[1].position.set(-2.15, -0.22, 0.51);
    plane[1].rotation.x += Math.PI / 2;
    plane[1].receiveShadow = true;

    var platGroup = new THREE.Group();
    platGroup.add(plane[0]);
    platGroup.add(plane[1]);
    platGroup.rotation.y -= 2;
    platGroup.position.y  = 1;

    coreGroup.add(platGroup);


    cube_box1.setFromObject(plane[0]);
    platformArr.push(cube_box1);

    cube_box2.setFromObject(plane[1]);
    platformArr.push(cube_box2);
}

THREE.Sphere.__closest = new THREE.Vector3();
THREE.Sphere.prototype.intersectsBox = function(box) {
    // get box closest point to sphere center by clamping
    THREE.Sphere.__closest.set(this.center.x, this.center.y, this.center.z);
    THREE.Sphere.__closest.clamp(box.min, box.max);

    var distance = this.center.distanceToSquared(THREE.Sphere.__closest);
    return distance < (this.radius * this.radius);
};

function isCollision() {
    for (var i = 0; i < platformArr.length; i++) {
        _cubeBox = platformArr[i];
        return sphereBox.intersectsBox(_cubeBox);
    }
}

function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);

    if (collision) { // ball is on surface
        vy = -vy;
        collision = false;
    }

    cy -= vy * dt;

    sphere.position.y = cy;

    if (vy <= mvy)
        vy += gravity;

    collision = isCollision();
}


function addBall(){
 
    sphere = new THREE.Mesh(
        new THREE.SphereGeometry(0.19, 20, 20), materials.solid);
    sphere.position.set(0, 1, -2);
    sphere.geometry.computeBoundingSphere();
    scene.add(sphere);

    sphereBox = new THREE.Sphere(sphere.position, sphere.geometry.boundingSphere.radius);
    sphereBox.radius = sphere.geometry.boundingSphere.radius;
	
	cy = sphere.position.y;
}   

Complete code is here threecode.js (3.7 KB)

I suggest you try to use Box3.applyMatrix4 and Sphere.applyMatrix4 in order to apply the world matrix of a bounding volume’s mesh each frame. In this way, the transformation of superior objects like the group should be taken into account.

1 Like

Crossposting:

Can you help me how to use Box3.applyMatrix4 ?.
Still collision is not detected.
I am using it this way.

Code to create boxMesh and box3

 var box3 = new THREE.Box3(new THREE.Vector3(), new THREE.Vector3());

 var boxMesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0.2), materials.solid);
 boxMesh.position.set(-2.15, -0.22, 0.51);
 boxMesh.rotation.x += Math.PI / 2;
 scene.add(boxMesh);
 box3.applyMatrix4(boxMesh.matrixWorld);
 //box3.applyMatrix4(boxMesh.matrix); // I have used this also but no luck

Code to create sphereMesh and sphere

 var sphereMesh = new THREE.Mesh(
     new THREE.SphereGeometry(0.19, 20, 20), materials.solid);
 sphereMesh.position.set(0, 1, -2);
 sphereMesh.geometry.computeBoundingSphere();
 scene.add(sphereMesh);

 var sphere = new THREE.Sphere(sphereMesh.position, sphereMesh.geometry.boundingSphere.radius);

Code to detect collision

 return sphere.intersectsBox(box3);

THREE.Sphere.__closest = new THREE.Vector3();
THREE.Sphere.prototype.intersectsBox = function(box) {
    // get box closest point to sphere center by clamping
    THREE.Sphere.__closest.set(this.center.x, this.center.y, this.center.z);
    THREE.Sphere.__closest.clamp(box.min, box.max);

    var distance = this.center.distanceToSquared(THREE.Sphere.__closest);
    return distance < (this.radius * this.radius);
};

SOLVED

I found a way to get collision

var boxVector = new THREE.Vector3();
boxVector.setFromMatrixPosition(box3.matrixWorld);

var spherePos = sphereMesh.position.clone();
var yPoint = boxVector.y - spherePos.y;

if (yPoint <= 1 && yPoint >= -0.3) { // adjust values according to your game
    //console.log("hit");
    return true;
}

Thanks for the help !