user1584421
user1584421

Reputation: 3863

Very weird behaviour when scaling objects

I am trying to scale object through parameters at a GUI box

This is the code:

    window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;


params = {
  yAxis: "0.00001"
}
var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => {
  cube.scale.y = parseFloat(val);
}); 


 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";


    function init() {

        scene = new THREE.Scene();


        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;


        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer


        document.getElementById("WebGL-output").appendChild(renderer.domElement);  

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 0.00001, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xffff00 }); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.userData.originalColor = 0xffff00;


        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);


        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    }

    function onDocumentMouseMove(event)
    {

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            cube.material.color.set( 0xff0000 );
        } 
        else if (isClicked === false)
        {
            cube.material.color.set( cube.userData.originalColor );
        }

    }

    function onDocumentMouseClick(event) 
    {

        event.preventDefault();


        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;


        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";


        } 
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        {
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        }


    }


    function render() 
    {

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera); 
    }


    function animate()
    {
        requestAnimationFrame( animate ); 
        render();
    }
<!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

</body>
</html>

There is very weird behaviour that i cannot understand why it happens:

More specifically:

If i leave the cube as it is in the code (20, 0.00001, 20) Then the y parameter cannot be changed from the GUI. X and z get changed but if, for example i give the value 2, they mesh gets bigger. How is that possible that from 20, to 2, the mesh gets bigger?

I experimented with changing the cube constructor and i used (20,20,20) Now the y gets changed, but it always gets bigger as well....

Summing up, MY QUESTIONS:

1) When the values are initialized at 20... Why does a new values that is less than 20 make the mesh appear bigger?

2) When the y parameter has an initial value of 0.00001... Why it cannot be changed from the GUI at all?

Upvotes: 1

Views: 203

Answers (1)

M -
M -

Reputation: 28497

This is because cube.scale acts as a multiplication to the geometry, but it's multiplying a very small number.

Think of it this way, you have the Geometry and the Mesh, and Mesh.scale multiples the values of the geometry. Let's just look at the Y value:

Geometry.y = 0.00001
Mesh.scale.y = 1
Visible height = 0.00001 * 1 = 0.00001;

// Now if you change the scale of y to 20
Geometry.y = 0.00001
Mesh.scale.y = 20
Visible height = 0.00001 * 20 = 0.0002;

The problem is that you're initiating your geometry to be very small. You should change your geometry to start with larger values, and apply the scaling to the Mesh:

var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.scale.y = 0.00001;

window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;


params = {
  yAxis: "0.00001"
}
var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => {
  cube.scale.y = parseFloat(val);
}); 


 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";


    function init() {

        scene = new THREE.Scene();


        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;


        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer


        document.getElementById("WebGL-output").appendChild(renderer.domElement);  

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xffff00 }); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.scale.y = 0.00001;
        cube.userData.originalColor = 0xffff00;


        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);


        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    }

    function onDocumentMouseMove(event)
    {

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            cube.material.color.set( 0xff0000 );
        } 
        else if (isClicked === false)
        {
            cube.material.color.set( cube.userData.originalColor );
        }

    }

    function onDocumentMouseClick(event) 
    {

        event.preventDefault();


        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;


        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";


        } 
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        {
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        }


    }


    function render() 
    {

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera); 
    }


    function animate()
    {
        requestAnimationFrame( animate ); 
        render();
    }
<!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

</body>
</html>

Upvotes: 2

Related Questions