0

We are able to detect the collision but could not implement a snapping/magnetic effect like Snap edges of objects to each other and prevent overlap we need help with 3D objects here and we are using Vec3 for the active object's position.

With the following approach, collision detection is working perfectly for all cases, and magnetic effect is somehow working - not perfectly. It's working well when the object is moving along x or z-axis but when the object's movement is in diagonal direction (moving along x and z-axis simultaneously) that is where the problem comes.

Though am not satisfied with the following approach that's why am looking for new approach to implement both magnetic and collision detection features. It is not necessary to have the solution in Threejs, any general solution or algorithm of coordinates can be converted into Threejs.

        let collide = this.detectCollisionCubes(activeObject, collidingObject, vec3);
  
        let magneticEffect = new MagneticEffect(activeObject, vec3, collidingObject);
        vec3 = magneticEffect.setNewPosition(); 
        activeObject.position.copy(vec3); 
             

        detectCollisionCubes = function(a, d, vec3){
            // a is active object's positon
            // d is colliding object                        
   
            let aHeight = Math.abs(a.getHeight());
            let aWidth = Math.abs(a.getWidth());
            let aDepth = Math.abs(a.getDepth());

            let b1 = vec3.y - aHeight / 2;
            let t1 = vec3.y + aHeight / 2;

            let r1 = vec3.x + aWidth / 2;
            let l1 = vec3.x - aWidth / 2;

            let f1 = vec3.z - aDepth / 2;
            let B1 = vec3.z + aDepth / 2;

            let dHeight = Math.abs(d.getHeight());
            let dWidth = Math.abs(d.getWidth());
            let dDepth = Math.abs(d.getDepth());
            
            let b2 = d.position.y - dHeight / 2;
            let t2 = d.position.y + dHeight / 2;

            let r2 = d.position.x + dWidth / 2;
            let l2 = d.position.x - dWidth / 2;

            let f2 = d.position.z - dDepth / 2;
            let B2 = d.position.z + dDepth / 2;
            
            if (t1 < b2 || r1 < l2 || b1 > t2 || l1 > r2 || f1 > B2 || B1 < f2) {
              return false;
            }

            return true;
        }

Trying to create magnetic effect via

    this.currentObject = currentObject;
    this.collisionObject = collisionObject;
    this.collisionType = null;
    this.objectType = null;
    this.currentPosition = currentPosition; 

    this.currentObjectHeight = Math.abs(currentObject.getHeight());
    this.currentObjectWidth = Math.abs(currentObject.getWidth());

    this.collisionObjectHeight = Math.abs(collisionObject.getHeight());
    this.collisionObjectWidth = Math.abs(collisionObject.getWidth());
    this.collisionObjectDepth = Math.abs(collisionObject.getDepth());

    this.objectTop = currentObject.position.y + (this.currentObjectHeight/2);
    this.objectBottom = currentObject.position.y - (this.currentObjectHeight/2);

    this.collideTop = collisionObject.position.y + (this.collisionObjectHeight/2);
    this.collideBottom = collisionObject.position.y - (this.collisionObjectHeight/2);

    this.zAxisDifference = Math.abs(Math.abs(currentPosition.z) - Math.abs(collisionObject.position.z));
    this.xAxisDifference = Math.abs(Math.abs(currentPosition.x) - Math.abs(collisionObject.position.x));
     
     // Extra code here   
     
    if (
        this.objectTop < this.collideBottom
    ) { 
        this.collisionType = collisionTypes.verticalBottom;
    } else if (
        this.objectBottom > this.collideTop
    ) { 
        this.collisionType = collisionTypes.verticalTop;
    } else if (
        this.currentPosition.x > this.collisionObject.position.x &&
        this.zAxisDifference < 2
    ) {
        this.collisionType = collisionTypes.horizentalXLeft;
    } else if (
        this.currentPosition.x < this.collisionObject.position.x &&
        this.zAxisDifference < 2
    ) {
        this.collisionType = collisionTypes.horizentalXRight;
    } else if (
        this.currentPosition.z > this.collisionObject.position.z &&
        this.xAxisDifference < 2
    ) {
        this.collisionType = collisionTypes.horizentalZLeft;
    } else if (
        this.currentPosition.z < this.collisionObject.position.z &&
        this.xAxisDifference < 2
    ) {
        this.collisionType = collisionTypes.horizentalZRight;
    }

 MagneticEffect.prototype.setNewPosition = function () {
    
    if (this.collisionType === collisionTypes.verticalBottom) {
        this.currentPosition.y = this.collideBottom + 0.5;
    } else if (this.collisionType === collisionTypes.verticalTop) {
        this.currentPosition.y = this.collideTop - 0.5;
    } else if (this.collisionType === collisionTypes.horizentalXRight) {
        this.currentPosition.x = this.collisionObject.position.x - this.collisionObjectWidth - 0.5;
    } else if (this.collisionType === collisionTypes.horizentalXLeft) {
        this.currentPosition.x = this.collisionObject.position.x + this.collisionObjectWidth + 0.5;
    } else if (this.collisionType === collisionTypes.horizentalZRight) {
        this.currentPosition.z = this.collisionObject.position.z - this.collisionObjectWidth - 0.5;
    } else if (this.collisionType === collisionTypes.horizentalZLeft) {
        this.currentPosition.z = this.collisionObject.position.z + this.collisionObjectWidth + 0.5;
    }

    return this.currentPosition;
};
  • You will need to provide more information. What do you have now? What have you tried? What happens? What did you expect to happen? Are there any errors? – TheJim01 Apr 01 '21 at 13:36
  • 1
    @TheJim01 Just updated the description. – Rashid Siddique Apr 01 '21 at 14:22
  • @TheJim01 Could you please help with this? – Rashid Siddique Apr 03 '21 at 06:27
  • @RashidSiddique I would suggest looking into rbush-3d and using the bounding boxes of the objects to detect collision. For snapping, the basic principle is look for closest potential snap, check if the snap is valid (is it close enough to the mouse?) then move your object to the new position. If you're dealing with a lot of objects you'll want to use something like rbush-3d. – Nick Gimbal Apr 07 '21 at 22:51
  • Thank you @NickGimbal, but I think, I might not be able to fix the diagonal movement issue - Mentioned in the description which is actually my main concern. – Rashid Siddique Apr 08 '21 at 15:05
  • @NickGimbal I am unable to predict collision points with diagonal movement, so i can add some snapping effect. Please see magnetic effect code. – Rashid Siddique Apr 08 '21 at 15:07

0 Answers0