BABYLON组件优化:一. Path3D组件getClosestPositionTo方法

在我最近做的一个地下钻探项目中,需要展示所有钻井设备协同钻进,并且需要实时获取钻头位置。在这个需求中我使用了babylonjs官方的Path3D组件进行辅助开发。

优化前

在开发的过程中发现Path3D组件的getClosestPositionTo方法十分消耗性能,不能满足实时同步钻头位置的需求。
性能消耗十分夸张

为了解决这个问题,于是我翻看源码,我将源码展示在下面。

public getClosestPositionTo(target: Vector3) {
        let smallestDistance = Number.MAX_VALUE;
        let closestPosition = 0.0;
        for (let i = 0; i < this._curve.length - 1; i++) {
            let point = this._curve[i + 0];
            let tangent = this._curve[i + 1].subtract(point).normalize();
            let subLength = this._distances[i + 1] - this._distances[i + 0];
            let subPosition = Math.min((Math.max(Vector3.Dot(tangent, target.subtract(point).normalize()), 0.0) * Vector3.Distance(point, target)) / subLength, 1.0);
            let distance = Vector3.Distance(point.add(tangent.scale(subPosition * subLength)), target);

            if (distance < smallestDistance) {
                smallestDistance = distance;
                closestPosition = (this._distances[i + 0] + subLength * subPosition) / this.length();
            }
        }
        return closestPosition;
    }

可以看到,组件在每次获取距离目标位置时会遍历数组,但实际项目中,钻头只会从停留位置沿着路径前后移动,不存在突然出现在某一处的情况,如果钻头向后移动我们可以反向遍历到极值,顺向同理。

优化方法

所以我给这个方法加上一个标记上次位置的虚拟指针,根据钻头的运动方向进行遍历,并且在达到极值的时候退出遍历,即可减少遍历次数。如果想要更好的性能表现还可以尝试二分法等。

优化后

帧时间可接受

这里看到帧时间下降到7ms左右。
在项目中,如果钻头不运动,帧时间大概在3ms左右。

# BABYLONJS 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×