Reputation: 3863
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
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