javascript - 如何使一组对象居中?

标签 javascript three.js

我开始使用 Three.js(新手),但我不知道如何更改一组对象的中心原点。在这个例子中 https://jsfiddle.net/spyf1j94/2/可以看到原点设置为添加到组中的第一个对象,问题是如何将这个原点设置为组中心?

var three = THREE;

var scene = new three.Scene();
var camera = new three.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

var renderer = new three.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);
camera.position.z = 30;
var cubeMatrix = new THREE.Object3D();

var nextHeight = 0;
for(var j = 0, x = 0, y = 0; j < 220; j++, x++) {
var z = Math.floor(Math.random() * 12) + 1;
    var geometry = new THREE.BoxGeometry(1,  1 , z);

    var material = new THREE.MeshBasicMaterial({vertexColors: THREE.VertexColors});

    var color = Math.random() * 0xFFFFFF;

    for(var i = 0; i < geometry.faces.length; i += 2) {
        geometry.faces[i].color.setHex(color);
      geometry.faces[i + 1].color.setHex(color);
    }
    var cube = new THREE.Mesh(geometry, material);
    cube.position.set(x,y,z/2);

    if (x === 10) {
        x = -1;
      y++;
    }

    //cube.position.y = y * 1;
    cubeMatrix.add(cube);

}

scene.add(cubeMatrix);
scene.add(new THREE.AxisHelper());


var isDragging = false;
var previousMousePosition = {
    x: 0,
    y: 0
};
$(renderer.domElement).on('mousedown', function(e) {
    isDragging = true;
})
.on('mousemove', function(e) {
    //console.log(e);
    var deltaMove = {
        x: e.offsetX-previousMousePosition.x,
        y: e.offsetY-previousMousePosition.y
    };

    if(isDragging) {

        var deltaRotationQuaternion = new three.Quaternion()
            .setFromEuler(new three.Euler(
                (Math.PI / 180) * (deltaMove.y * 1),
                (Math.PI / 180) * (deltaMove.x * 1),
                0,
                'XYZ'
            ));

        cubeMatrix.quaternion.multiplyQuaternions(deltaRotationQuaternion, cubeMatrix.quaternion);
    }

    previousMousePosition = {
        x: e.offsetX,
        y: e.offsetY
    };
});
/* */

$(document).on('mouseup', function(e) {
    isDragging = false;
});



// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
    return  window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function(callback) {
            window.setTimeout(callback, 1000 / 60);
        };
})();

function render() {
    renderer.render(scene, camera);
    requestAnimFrame(render);
}

render();

最佳答案

通过THREE.Box3()获取bbox的边界框

var bbox = new THREE.Box3().setFromObject(cubeMatrix);

cubeMatrix 替换为边界框的负半长和宽:

cubeMatrix.position.set(-(bbox.min.x + bbox.max.x) / 2, -(bbox.min.y + bbox.max.y) / 2, 0);

cubeMatrix添加到另一组pivot:

var pivot = new THREE.Group();
pivot.add(cubeMatrix);

并将组 pivot 添加到场景中:

scene.add(pivot);

"mousemove" 事件中旋转组 pivot 而不是 cubeMatrix:

if(isDragging) {

    var deltaRotationQuaternion = new three.Quaternion()
        .setFromEuler(new three.Euler(
            (Math.PI / 180) * (deltaMove.y * 1),
            (Math.PI / 180) * (deltaMove.x * 1),
            0,
            'XYZ'
    ));

    pivot.quaternion.multiplyQuaternions(deltaRotationQuaternion, pivot.quaternion);
}

查看示例,其中我将更改应用于您的原始代码:

var three = THREE;

var scene = new three.Scene();
var camera = new three.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

var renderer = new three.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);

container = document.getElementById('container');
container.appendChild(renderer.domElement);
camera.position.z = 30;
var cubeMatrix = new THREE.Object3D();

var nextHeight = 0;
for(var j = 0, x = 0, y = 0; j < 220; j++, x++) {
var z = Math.floor(Math.random() * 12) + 1;
    var geometry = new THREE.BoxGeometry(1,  1 , z);
    
    var material = new THREE.MeshBasicMaterial({vertexColors: THREE.VertexColors});
    
    var color = Math.random() * 0xFFFFFF;
    
    for(var i = 0; i < geometry.faces.length; i += 2) {
    	geometry.faces[i].color.setHex(color);
      geometry.faces[i + 1].color.setHex(color);
    }
    var cube = new THREE.Mesh(geometry, material);
    cube.position.set(x,y,z/2);
    
    if (x === 10) {
    	x = -1;
      y++;
    }
    
    //cube.position.y = y * 1;
    cubeMatrix.add(cube);
    
}
var bbox = new THREE.Box3().setFromObject(cubeMatrix);
cubeMatrix.position.set(-(bbox.min.x + bbox.max.x) / 2, -(bbox.min.y + bbox.max.y) / 2, 0);

var pivot = new THREE.Group();
pivot.add(cubeMatrix);

scene.add(pivot);
scene.add(new THREE.AxisHelper());


var isDragging = false;
var previousMousePosition = {
    x: 0,
    y: 0
};
container.addEventListener('mousedown', function(e) {
    isDragging = true;
});
container.addEventListener('mousemove', function(e) {
    //console.log(e);
    var deltaMove = {
        x: e.offsetX-previousMousePosition.x,
        y: e.offsetY-previousMousePosition.y
    };

    if(isDragging) {
            
        var deltaRotationQuaternion = new three.Quaternion()
            .setFromEuler(new three.Euler(
                (Math.PI / 180) * (deltaMove.y * 1),
                (Math.PI / 180) * (deltaMove.x * 1),
                0,
                'XYZ'
        ));
    
        pivot.quaternion.multiplyQuaternions(deltaRotationQuaternion, pivot.quaternion);
    }
    
    previousMousePosition = {
        x: e.offsetX,
        y: e.offsetY
    };
});
/* */

container.addEventListener('mouseup', function(e) {
    isDragging = false;
});

window.onresize = function() {
      renderer.setSize(window.innerWidth, window.innerHeight);
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
}

// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
    return  window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function(callback) {
            window.setTimeout(callback, 1000 / 60);
        };
})();

function render() {
    renderer.render(scene, camera);
    requestAnimFrame(render);
}

render();
<script src="https://threejs.org/build/three.min.js"></script>
<div id="container"></div>

关于javascript - 如何使一组对象居中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54611146/

相关文章:

javascript - 监听表并在发生变化时调用函数

three.js - 计算顶点法线

javascript - 如何在 THREE.TextGeometry 中添加带上标的字符串?

javascript - 有没有办法在 ThreeJs 中使用 dat.gui.js 构建范围 slider ?

javascript - 当 THREE.PlaneBufferGeometry 位于另一个对象内时,如何隐藏它的一部分?

javascript - 从输入的 url 到网页将数据接收到 javascript

javascript - Angular 无法在检查器中加载资源错误

javascript - 我可以在 d3 中加载 .gml 吗?

javascript - 尝试通过 node.js http 发布到 "read ECONNRESET"时出现 'graph.facebook.com' 错误

node.js - 如何开始使用 yeoman 和 Three.js?