Avoiding Collision between two boxes


Hi,
I want to avoid the merging of the two boxes when they collide.I’m able to detect the collision but don’t know how to avoid it from merging.Can anyone please suggest any method that fits here.Thanks
/***************************************************************************************************/

var dragControls = new THREE.DragControls( objects, camera, renderer.domElement);

var collision;

dragControls.addEventListener( 'drag', function ( event ) {

intersectObjMas(event.object,objects);

function intersectObjMas(obj, mas) {

     for (var i = 0; i < mas.length; i++) {

	     if(event.object != mas[i]){
		 
                    var firstObject = event.object;

                    var secondObject = mas[i];

                      firstBB = new THREE.Box3().setFromObject(firstObject);

                     secondBB = new THREE.Box3().setFromObject(secondObject);
                     
                     collision = firstBB.isIntersectionBox(secondBB);
                                                   }
                                                              }
                                                                    }

 if ( event.object.position.y < (event.object.geometry.parameters.height /2) ) {

   event.object.position.y = (event.object.geometry.parameters.height /2);  // this is to avoid the cube from passing thorugh the ground surface below

  } 
 else {

  	dragControls.addEventListener( 'dragstart', function ( event ) {

      controls.enabled = false;
  		
  	});

    dragControls.addEventListener( 'dragend', function ( event ) {

      controls.enabled = true;

    });

  };

});

You normally implement a basic collision detection test like so:

  • Save the current transformation of the moving object.
  • Apply the transformation of the current frame. In your case, this is done by DragControls when dragging an object in 3D space.
  • Now perform the collision detection test. In your case it’s an AABB/AABB intersection test.
  • If there is an intersection, restore the object’s transformation to the status of the last frame. Or in other words: Prevent the transformation of the current frame.
3 Likes

Could you suggest me any method to store the previous position.
I tried printing the before collision and after collision position but was getting the same value

var dragControls = new THREE.DragControls( objects, camera, renderer.domElement);

var collision;

dragControls.addEventListener( 'drag', function ( event ) {
 console.log('old position ' + event.object.position.x);
intersectObjMas(event.object,objects);

function intersectObjMas(obj, mas) {

     for (var i = 0; i < mas.length; i++) {

	     if(event.object != mas[i]){
		 
                    var firstObject = event.object;

                    var secondObject = mas[i];

                      firstBB = new THREE.Box3().setFromObject(firstObject);

                     secondBB = new THREE.Box3().setFromObject(secondObject);
                     
                     collision = firstBB.isIntersectionBox(secondBB);
 console.log('newposition ' + event.object.position.x);
                                                   }
                                                              }
                                                                    }

 if ( event.object.position.y < (event.object.geometry.parameters.height /2) ) {

   event.object.position.y = (event.object.geometry.parameters.height /2);  // this is to avoid the cube from passing thorugh the ground surface below

  } 
 else {

  	dragControls.addEventListener( 'dragstart', function ( event ) {

      controls.enabled = false;
  		
  	});

    dragControls.addEventListener( 'dragend', function ( event ) {

      controls.enabled = true;

    });

  };

});

You are currently logging not the “old position” in your drag event handler. The position vector was already changed at this point. So it’s better to create a Vector3 called currentPosition and save the position at the end of the handler e.g.

const object = event.object;
object.userData.currentPosition.copy( object.position );

You can create and init currentPosition when creating the actual object. In any event, you now have the current and the new position in the drag event handler and can then perform a restore if necessary.

1 Like

Hi Michael,Its not working in my case
This is the initial position


I wanted the position when they are this close (image 2)

(image 3) should not happen it must get back to image 2

Is there any other way

It seems you are doing something wrong in your code. It’s best to share your current work of process as a live example so it’s possible to debug the issue.

Newcontainermodel (1).zip (1.9 MB)
Hi michael i have attached the zip file related to the code.
The script file has all the code related to the cubes

Here is your updated scripts.js. I’ve only implemented what I’ve been described in my earlier post.

scripts.js (9.9 KB)

Tip: You have a lot of unused variables in your file. I can only recommend to clean your code up a bit. It’s very confusing to understand right now what parts are actually relevant.

1 Like

Thanks Michael,
The boxes were passing through the ground but were not overlapping each other due to the changes made. I made a few changes and now its working properly.
Thanks for your time and help
:slight_smile:

1 Like

I have the same problem; I am starting with ThreeJs. Could you pass me the project.

hi sebasthian the zip contains the collision avoidance code
Dragmodel.zip (916.5 KB)

You have put camera inside box but it is not stopping it to get inside another box, why?

Just a word of caution here. The above solution works really well in avoiding overlaps.
However, this method depends on the drag speed of the cursor.

As an example: if you try to drag and move one box towards the other, the spacing will be depending on on speed of the cursor moved in that direction,
The greater the speed, the greater the gap.
Even if anyone try to move the object really slow, it still won’t be 100% snapping.

In this case, am asssuming, there will need additional computation to support snapping to the nearest vertex or the face.