Scaling a Three.js geometry only up

≡放荡痞女 提交于 2019-12-18 17:55:47

问题


I'm trying to scale the geometries y-axis. This made my cube scale both up and down. I think mesh.transformY works to animate the cube up half of the scaling value. This would make it look like the cube just scaled upwards. Are there other solutions for this?

    var geometry = new THREE.BoxGeometry(1, 1, 1);
    var mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({
        color: 0xffffff
    }));

    mesh.position.set(0, 2, 0);
    mesh.scale.set(0.98, 0.95, 0.992);
    mesh.castShadow = true;
    scene.add(mesh);

    var tween = new TWEEN.Tween(mesh.scale)tween.to({y: 2}, 1000)
    tween.easing(TWEEN.Easing.Elastic.InOut);
    tween.yoyo(true);
    tween.start();

回答1:


The usual case of your question is something on a 'ground', like a 'person' mesh, that shall always have its feet on the ground whatever its size. There are two ways for that.

  • The way Evilzebra proposed in the comment. Based on the height of your mesh you can implement it easily : as you wrote, when scaling in y, the mesh will get half taller both on top and bottom. So you just have to move its position to height * scale / 2 :

    function scaleY ( mesh, scale ) {
        mesh.scale.y = scale ;
        if( ! mesh.geometry.boundingBox ) mesh.geometry.computeBoundingBox();
        var height = mesh.geometry.boundingBox.max.y - mesh.geometry.boundingBox.min.y;
        //height is here the native height of the geometry
        //that does not change with scaling. 
        //So we need to multiply with scale again
        mesh.position.y = height * scale / 2 ;
    }
    
  • Another way is to move the origin of the coordinates (local space) at the bottom of the geometry, so the position is not changed. For that you have to move the origin of the geometry to the lowest y coordinate. You will then be able to change your scale at will with the native ThreeJS method :

    function originToBottom ( geometry ) {
    
        //1. Find the lowest `y` coordinate
        var shift = geometry.boundingBox ? geometry.boundingBox.min.y : geometry.computeBoundingBox().min.y;
    
        //2. Then you translate all your vertices up 
        //so the vertical origin is the bottom of the feet :
        for ( var i = 0 ; i < geometry.vertices.length ; i++ ) {
            geometry.vertices[ i ].y -= shift;
        }
        //or as threejs implements (WestLangley's answer) : 
        geometry.translate( 0, -shift, 0);
    
        //finally
        geometry.verticesNeedUpdate = true;
    }
    



回答2:


If you want your geometry to scale only "up", all you need to do is make sure the "bottom" of your geometry passes through the origin. In your case, you can use the translate() method like so:

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

var tween = new TWEEN.Tween( mesh.scale ).to( { y: 2 }, 1000 );
tween.start();

The bottom of the box will remain fixed, and the box's height will change.

three.js r.73




回答3:


Since this is, in my case, the first item on Google on how to scale a geometry I'll post my function to alter a geometry.

function _alterGeometry(geometry, opt) {

    var toAlter = [];

    var matrixMultiplier = function (mtx) {
        var matrix = new THREE.Matrix4();
        mtx.forEach(function (m, index) {
            matrix = new THREE.Matrix4().multiplyMatrices(matrix, m);
        });
        return matrix;
    };

    if (opt.position)
        toAlter.push(new THREE.Matrix4().setPosition(new THREE.Vector3(opt.position.x, opt.position.y, opt.position.z)));

    if (opt.rotation && opt.rotation.x)
        toAlter.push(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), opt.rotation.x));

    if (opt.rotation && opt.rotation.y)
        toAlter.push(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0), opt.rotation.y));

    if (opt.rotation && opt.rotation.z)
        toAlter.push(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), opt.rotation.z));

    if (opt.scale)
        toAlter.push(new THREE.Matrix4().scale(opt.scale));

    geometry.applyMatrix(matrixMultiplier(toAlter));
    return geometry;

}


来源:https://stackoverflow.com/questions/33454919/scaling-a-three-js-geometry-only-up

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!