微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Threejs 实现两个物体之间的捕捉效果和碰撞检测?

如何解决如何使用 Threejs 实现两个物体之间的捕捉效果和碰撞检测?

我们能够检测到碰撞,但无法实现像 Snap edges of objects to each other and prevent overlap 这样的捕捉/磁性效果 我们在此处需要有关 3D 对象的帮助,我们使用 Vec3 来确定活动对象的位置。

使用以下方法,碰撞检测在所有情况下都能完美运行,并且磁效应在某种程度上起作用 - 不完美。 当对象沿 x 轴或 z 轴移动时它运行良好,但当对象沿对角线方向移动(同时沿 x 和 z 轴移动)时,问题就来了。

虽然我对以下方法不满意,这就是为什么我正在寻找新方法来实现磁性和碰撞检测功能。 Threejs中不需要有解,任何通用的坐标解或算法都可以转换成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;
        }

尝试通过

创造磁性效果
    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;
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?