在屏幕中央渲染STL文件

Three.js Position Rendered STL file in the center of screen

本文关键字:STL 文件 屏幕      更新时间:2023-09-26

我有一个从Thingiverse渲染的STL文件显示与Three.js使用THREE.STLLoader()加载源文件。我的问题是我不知道如何定位它在屏幕的中心,只能这样做通过调整旋转属性,我正在修改使用事件触摸坐标。我试着把对象放在屏幕的中心,当我在屏幕上移动手指时从中心旋转。

这是我目前所拥有的,任何帮助都会很感激:

var container, stats;
var camera, scene, renderer;
var stlMesh;
var mesh, geometry;
var loader;
var directionalLight;
var mouseX = 0;
var mouseY = 0;
var zoom = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
// Ejecta; Added for touch controls:
document.addEventListener('touchmove', onDocumentTouchMove, false);
function init() {
    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.2, 100);
    scene = new THREE.Scene();
    scene.add(camera);
    // light
    var dirLight = new THREE.DirectionalLight(0xffffff);
    dirLight.position.set(200, 200, 1000).normalize();
    scene.add(dirLight);
    // STL
    var loader = new THREE.STLLoader();
    loader.load(window.filePath, function(geometry) {
        var material = new THREE.MeshPhongMaterial({
            color: 0xffff00,
            specular: 0x111111,
            shininess: 200
        });
        stlMesh = new THREE.Mesh(geometry, material);
        stlMesh.position.set(0, -0.25, 0.6);
        stlMesh.rotation.set(0, -Math.PI / 2, 0);
        stlMesh.scale.set(0.5, 0.5, 0.5);
        stlMesh.castShadow = true;
        stlMesh.receiveShadow = true;
        scene.add(stlMesh);
    });
    // renderer
    renderer = new THREE.WebGLRenderer({
        canvas: document.getElementById('canvas'),
        alpha: true
    });
    renderer.setClearColor(0x000000, 0); // the default
    renderer.setSize(window.innerWidth, window.innerHeight);
    container = document.createElement('div');
    document.body.appendChild(container);
    container.appendChild(renderer.domElement);
    window.addEventListener('resize', onWindowResize, false);
}
function getCentroid(mesh) {
    mesh.geometry.computeBoundingBox();
    var boundingBox = mesh.geometry.boundingBox;
    var size = boundingBox.size();
    console.log(size.x, size.y, size.z);
    var x0 = boundingBox.min.x;
    var x1 = boundingBox.max.x;
    var y0 = boundingBox.min.y;
    var y1 = boundingBox.max.y;
    var z0 = boundingBox.min.z;
    var z1 = boundingBox.max.z;
    var bWidth = (x0 > x1) ? x0 - x1 : x1 - x0;
    var bHeight = (y0 > y1) ? y0 - y1 : y1 - y0;
    var bDepth = (z0 > z1) ? z0 - z1 : z1 - z0;
    var centroidX = x0 + (bWidth / 2) + mesh.position.x;
    var centroidY = y0 + (bHeight / 2) + mesh.position.y;
    var centroidZ = z0 + (bDepth / 2) + mesh.position.z;
    return mesh.geometry.centroid = {
        x: centroidX,
        y: centroidY,
        z: centroidZ
    };
}
function onWindowResize() {
    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}
// Ejecta; Added for touch controls
function onDocumentTouchMove(event) {
    //mouseX = ( event.touches[0].clientX - windowHalfX ) * 4;
    //mouseY = ( event.touches[0].clientY - windowHalfY ) * 4;
    //mouseX = event.touches[0].clientX-180
    //mouseY = event.touches[0].clientY-180
    if (event.touches.length == 1) {
        // Roation Action
        mouseX = degInRad(event.touches[0].clientX)
        mouseY = degInRad(event.touches[0].clientY)
    } else if (event.touches.length == 2) {
        positionY1 = event.touches[0].clientY
        positionY2 = event.touches[1].clientY
        if (positionY2 > positionY1) {
            t1 = positionY1
            positionY1 = positionY2
            positionY2 = t1
        }
        zoom = (positionY1 - positionY2) / window.innerHeight
        zoom = zoom > 0.9 ? 0.9 : zoom
    }
}
function animate() {
    requestAnimationFrame(animate);
    render();
}
function degInRad(deg) {
    return deg * Math.PI / 180;
}
function render() {
    var timer = -0.0002 * Date.now();
    // OLD
    //camera.position.x += ( mouseX - camera.position.x ) * .05;
    //camera.position.y += ( - mouseY - camera.position.y ) * .05;
    //camera.lookAt(stlMesh.position);
    //scene.rotation.copy( camera.rotation );
    // NEW
    stlMesh.rotation.y = mouseX;
    stlMesh.rotation.x = mouseY;
    //stlMesh.rotation.y = 4.790928796724434;
    //stlMesh.rotation.x = 3.3073989325292543;
    //stlMesh.position.z = camera.position.z*zoom
    //console.log(stlMesh.position.x, stlMesh.position.y)
    //console.log("Z: "+stlMesh.position.z)
    renderer.render(scene, camera);
}

我似乎在阅读了Three.js源代码后找到了答案,关键是在创建网格之前将几何形状"中心"。这是我新的three。stloader ();加载方法:

// STL
var loader = new THREE.STLLoader();
loader.load(window.filePath, function ( geometry ) {
    geometry.center()
    var material = new THREE.MeshLambertMaterial({color: 0x55B663});
    stlMesh = new THREE.Mesh(geometry, material);
    camera.position.z = geometry.boundingBox.size().z+300
    //stlMesh.translateY()
    scene.add(stlMesh);
});