简体   繁体   English

Three.js将渲染的STL文件放置在屏幕中央

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

I have a rendered STL file from Thingiverse displaying with Three.js using the THREE.STLLoader() load the source files. 我有一个Thingiverse渲染的STL文件,使用THREE.STLLoader()与Three.js一起显示,以加载源文件。 My problem is I don't know how to position it in the center of the screen and can only do so by adjusting the roation properties which I'm modifying using the event touch coordinates. 我的问题是我不知道如何将其放置在屏幕中央,只能通过调整事件属性(使用事件触摸坐标修改)的旋转属性来实现。 I'm trying to get the object in the center of the screen and roatate from the center when I move my finger over the screen. 我试图将对象放在屏幕中央,并在将手指移到屏幕上方时从该中心旋转。

This is what I currently have, any help would be appreciated: 这是我目前拥有的,将不胜感激:

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);
}

I seem to have found the answer after reading through the Three.js sourcecode, the key was to 'center' the geometry before creating the mesh. 在阅读Three.js源代码之后,我似乎找到了答案,关键是在创建网格之前将几何“居中”。 Here's my new THREE.STLoader(); 这是我新的THREE.STLoader(); load method: 加载方式:

// 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);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM