Three.js - 旋转后更大的边界框

时间:2018-06-19 00:50:53

标签: javascript three.js

所以我有这个代码:

computeCarBoundingBox(mesh);

mesh.rotation.x = this.rotationVal[ 0 ];
mesh.rotation.y = this.rotationVal[ 1 ];
mesh.rotation.z = this.rotationVal[ 2 ];

我尝试计算网格的边界框,如果我在旋转后计算它,请看如下: First pic

如果我在旋转之后计算它,看起来像这样: Second

second picture from the top

我的计算bounfind框函数是这样的:

function computeCarBoundingBox(mesh){

        var box = new THREE.Box3().setFromObject(mesh);

        var boundingBoxHelper = new THREE.Box3Helper( box, 0xffff00 );  
        scope.carBoundingBox =boundingBoxHelper;
        scene.add(scope.carBoundingBox);
        console.log(box.min); // x, y, and z are all Infinity.
        console.log(box.max); // x, y, and z are all -Infinity.


}

我确实有几何形状。这是我的代码的一部分:

this.loadCar = function ( carsVector,carName,roadName ) {
    if(carName=='veyron')
    {
        var index = 0;

    }
    else if(carName=='F50')
    {
        var index = 1;
    }
    else
    {
        var index = 2;
    }
    console.log("Selected car name:"+carName);
    var carLoader = new THREE.BinaryLoader();
    carLoader.load( carsVector[Object.keys(carsVector)[index]].url, function( geometry ) { 

        geometry.sortFacesByMaterialIndex();
        console.log("url--->"+carsVector[Object.keys(carsVector)[index]].url);


        var materials = [];
        this.scaleVal = carsVector[ Object.keys(carsVector)[index] ].scale * 1;
        if(roadName =='road01'){
            this.positionVal = carsVector[ Object.keys(carsVector)[index] ].position_r1;
        }
        else if(roadName=='road02'){
            this.positionVal = carsVector[ Object.keys(carsVector)[index] ].position_r2;
        }

        this.rotationVal = carsVector[ Object.keys(carsVector)[index] ].init_rotation;


        for ( var i in carsVector[ Object.keys(carsVector)[index] ].materialsMap ) {
            materials[ i ] = carsVector[ Object.keys(carsVector)[index] ].materialsMap[ i ];
        }
        createObject(geometry,materials);
    });

    return scope.carMesh;

}


    // internal helper methods

function createObject ( geometry, materials ) {

    scope.carGeometry = geometry;
    scope.carMaterials = materials;

    createCar();

};

function createCar () {
    console.log("CREATE CARRRRRRRRRRRRRRRRR");
    if ( scope.carGeometry ) {
        var carMaterial = new THREE.MeshFaceMaterial( scope.carMaterials );
        var mesh = new THREE.Mesh( scope.carGeometry, carMaterial );



        mesh.scale.x = mesh.scale.y = mesh.scale.z = this.scaleVal;

        mesh.position.set( this.positionVal[0], this.positionVal[1], this.positionVal[2]);



                mesh.rotation.x = this.rotationVal[ 0 ];
                mesh.rotation.y = this.rotationVal[ 1 ];
                mesh.rotation.z = this.rotationVal[ 2 ];
                this.carMesh = mesh;

                //
                    computeCarBoundingBox(mesh);

                console.log("This car mesh"+this.carMesh);
                addShadows();
                scene.add(this.carMesh);

                //this.carBoundingBox.rotation.x =this.r[0];
                //this.carBoundingBox.rotation.y = this.r[1];
                //this.carBoundingBox.rotation.z = this.r[2];
                //scene.add( this.carBoundingBox );
    }

    if ( scope.callback ) {

        scope.callback(this.carMesh);

    }

}

3 个答案:

答案 0 :(得分:0)

好吧我有两个理论,但没有一定的答案。遗憾!

1)网格可能没有几何体。你的网格有几何形状吗?如果不是,代码called from setFromObject将失败。 (自上次makeEmpty调用以来,将永远不会调用expandByPoint,并且min和max将保持在Infinity)。

2)看到递归" expandByOject"代码在范围和this上,我会尝试在新的操作符var box = (new THREE.Box3()).setFromObject(mesh);中添加括号。它在黑暗中有点像,但也许范围从未正确设置。

很抱歉没有花时间和先测试一下。

答案 1 :(得分:0)

这就是.setFromObject()的工作方式,当物体很宽时,当你旋转它时,它的盒子会更大,因为它是世界轴对齐的:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 5, 5);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xffffff, 0.75);
light.position.set(-10, 10, -10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));

scene.add(new THREE.GridHelper(10, 10));

var geometry = new THREE.BoxGeometry(2, 1, 3);
geometry.translate(0, 0.5, 0);

var mesh1 = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
  color: "gray"
}));
mesh1.position.x = -2.5;
scene.add(mesh1);

var mesh2 = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
  color: "aqua"
}));
mesh2.position.x = 2.5;
mesh2.rotation.y = THREE.Math.degToRad(45);
scene.add(mesh2);

var bbox1 = new THREE.Box3().setFromObject(mesh1);
var bbox2 = new THREE.Box3().setFromObject(mesh2);

var bhelp1 = new THREE.Box3Helper(bbox1, 0xffff00);
scene.add(bhelp1);
var bhelp2 = new THREE.Box3Helper(bbox2, 0xff00ff);
scene.add(bhelp2);

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

答案 2 :(得分:0)

这些是我在项目中使用的方法,我在其中旋转后添加了边界框。如果您不先旋转,则不需要AdjustRelativeTo步骤,例如https://codepen.io/seppl2019/pen/zgJVKM enter image description here

class ChildPart {
  constructor(mesh) {
    this.mesh=mesh;
    this.boxwire=null;
  }

  // add my bounding box wire to the given mesh
  addBoundingBoxWire(toMesh) {
    var boxwire = new THREE.BoxHelper(this.mesh, 0xff8000);
    this.boxwire=boxwire;
    ChildPart.adjustRelativeTo(boxwire,toMesh);
    toMesh.add(boxwire);
  }

  static adjustRelativeTo(mesh,toMesh) {
    //logSelected("adjusting toMesh",toMesh);
    //logSelected("beforeAdjust",this.mesh);
    toMesh.updateMatrixWorld(); // important !
    mesh.applyMatrix(new THREE.Matrix4().getInverse(toMesh.matrixWorld));
    //logSelected("afterAdjust",this.mesh);
  }
}