how to set the first lookAt/target of a Control - javascript

I need to set the initial 'lookAt' point of the scene, that will be the center of the screen and of the control's rotation.
If possible, I would prefer to set a point (or an object's position), not rotation angles.
The control is OrbitControl. If I simply set lookAt before the Control initialization, the center is restored to (0,0,0) on the first user interaction, which causes a 'gap' ...
// camera
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 0.1, 20000);
camera.position.set(0,20,20);
camera.lookAt(new THREE.Vector3(0,10,0));
// controls
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
How can I set the initial point in a proper way?

Try setting the control's target and remove the camera.lookAt call:
controls.target = new THREE.Vector3(0, 10, 0);
controls.update();

Or more directly (without instanciating a new THREE.Vector3 but updating the values):
controls.target.set(0, 10, 0);
NB: controls.update() advice still remains for the 1st frame

Related

Flip camera upside down three.js

I am using PerspectiveCamera and OrbitControls and i am wondering if i could completely flip the camera so it’s basically upside down (making the scene apear upside down)? it would also be handy to know how to change it back again to the right way up!
thanks in advance
EDIT: FROM #WestLangley suggestion
You only have to turn the camera upside down with this camera.up.set(0, -1, 0); after your camera definition.
camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 0, 1000);
camera.up.set(0, -1, 0);
Just set it again to 0 whenever you want to restore to the regular position, so if you are thinking on flipping it based on any user interaction, I'd recommend to use a variable.
//somewhere in your code
let flipped = true; //or false depending any user interaction assigned
camera.up.set(0, (flipped ? -1: 0), 0);

Move camera and update its orbitControl in three js

I'm trying to change the camera position in the code and update the controller base on it.
Easily, I run:
camera.position.x = 20;
controls.update();
but this doesn't work at all !
controls.update() reset the camera position !
take webgl_decals as example, just declare the controller out of init() function, (so that you can call it in console), in console, run:
camera.position.x = 20;
controls.update();
the camera position will reset and will not change its position !
Is this the right way of of changing the camera position ?
any solution ?
If you are using OrbitControls and you want to set the camera position programmatically, you can do so by using the following pattern:
controls.enabled = false;
camera.position.set( 10, 10, 10 );
camera.lookAt( controls.target );
controls.enabled = true;
three.js r.97
Ok i found the solution, i was trying to update the camera by changing camera.position , instead I changed controls.target and it works !
Please take into consideration updating the controller by controls.update() after making this change.

three.js DirectionalLight and shadow cut off

As per the screenshot, shadows cast onto the THREE.PlaneGeometry(250, 380, 1, 1) below are cut off.
Steps I've taken to enable shadows
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
..
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 1000);
..
mainLight = new THREE.DirectionalLight(0xffffff, 0.5);
mainLight.position.set(50, 50, 50);
mainLight.castShadow = true;
mainLight.shadow.mapSize.width = width * window.devicePixelRatio;
mainLight.shadow.mapSize.height = width * window.devicePixelRatio;
mainLight.shadow.camera.near = 1;
mainLight.shadow.camera.far = 1000;
mainLight.shadow.camera.fov = 100;
scene.add(mainLight);
..
plane.receiveShadow = true;
..
model.castShadow = true;
model.receiveShadow = true;
I've played with different values like the shadow camera FOV and far plane values...
Is this a caveat with using DirectionalLight? I need even lighting across all of my models, as opposed to SpotLight.
I found three.js shadow cutoff but it simply suggested using a SpotLight instead and gave no explanation as to why that changes anything.
When I do use a SpotLight, I suddenly lose shadows on ground plane altogether.
--
Thanks
See the three.js documentation for DirectionalLightShadow:
This is used internally by DirectionalLights for calculating shadows.
Unlike the other shadow classes, this uses an OrthographicCamera to calculate the shadows, rather than a PerspectiveCamera. This is because light rays from a DirectionalLights are parallel.
See further DirectionalLight
A common point of confusion for directional lights is that setting the rotation has no effect. This is because three.js's DirectionalLight is the equivalent to what is often called a 'Target Direct Light' in other applications.
This means that its direction is calculated as pointing from the light's position to the target's position (as opposed to a 'Free Direct Light' that just has a rotation component).
The reason for this is to allow the light to cast shadows - the shadow camera needs a position to calculate shadows from.
This means that the area affected by the shadow is defined by the position and the camera of the light source (DirectionalLight).
Set up the camera for the mainLight and define its orthographic projection for your needs:
mainLight.shadow.camera = new THREE.OrthographicCamera( -100, 100, 100, -100, 0.5, 1000 );

New to three.js, how to animate this ball in three.js

Hi I'm just learning webGL and javascript.
I've made this three.js webGL scene thing, and actually come to think of it... They're the same object
http://goo.gl/gOiHX4
The ball is 'joined' to the rest of the 3d object, so I'll make a another sphere in blender by itself.
So say I have a ball.js and the rest of the structure, tribunal.js
how would I mode the ball.js along the 3D environment in this case?
Like maybe in a circle around the structure. constant loop.
pastebin for code too:
http://paste.ubuntu.com/6549663/
<!doctype html>
<html lang="en">
<head>
<title>My 3D webGL experiment</title>
<meta charset="utf-8">
</head>
<body style="margin: 0;">
<script src="js/three.min.js"></script>
<script src="js/OrbitControls.js"></script>
<script>
// Set up the scene, camera, and renderer as global variables.
var scene, camera, renderer;
init();
animate();
// Sets up the scene.
function init() {
// Create the scene and set the scene size.
scene = new THREE.Scene();
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
// Create a renderer and add it to the DOM.
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(WIDTH, HEIGHT);
document.body.appendChild(renderer.domElement);
// Create a camera, zoom it out from the model a bit, and add it to the scene.
camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 20000);
camera.position.set(90,80,0);
scene.add(camera);
// Create an event listener that resizes the renderer with the browser window.
window.addEventListener('resize', function() {
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
});
// Set the background color of the scene.
renderer.setClearColorHex(0xB5DBDB, 1);
// Create a light, set its position, and add it to the scene.
var light = new THREE.PointLight(0xf44fff);
light.position.set(200,200,200);
scene.add(light);
// Load in the mesh and add it to the scene.
var loader = new THREE.JSONLoader();
loader.load( "models/tribunal.js", function(geometry){
var material = new THREE.MeshLambertMaterial({color: 0xCC0000});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
// Add OrbitControls so that we can pan around with the mouse.
controls = new THREE.OrbitControls(camera, renderer.domElement);
}
// Renders the scene and updates the render as needed.
function animate() {
// Read more about requestAnimationFrame at http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
requestAnimationFrame(animate);
// Render the scene.
renderer.render(scene, camera);
controls.update();
}
</script>
</body>
</html>
In THREE.js, any movement of an object can be accomplished by changing its properties: position, rotation and/or scale. These properties are not simple numbers, so changing them to suit your needs often requires using built-in functions to be sure the change is handled correctly. For example, the position of a mesh is defined as a Vector which can be changed using the set() function like so:
mesh.position.set( 0, 0, 0 ); // Standard [ x, y, z ] coordinate system
There are many other ways to change the values in a Vector described in the documentation and code. Think of the properties of an object as objects themselves, and familiarize yourself with the methods available to you for those objects and their parent objects.
To answer your question: continuously moving an object over a period of time requires more code inside your animate() function. The following code will move a mesh 1 unit in a positive direction along the x-axis every time the animate() function is called:
mesh.position.translateX( 1 );
Tips:
There are many types of movement, but they are mostly combinations of position, rotation, and/or scale.
It is important to remember that child objects are affected by parent objects. If Mesh B is attached to Mesh A, movement applied to Mesh A will move Mesh B as well.
Variable references to objects inside your animate() loop need to be global so the animate() loop knows what object you are talking about.
Changes in position, scale and even rotation can quickly move an object out of frustum (or field-of-view) of the camera.
Use OrbitControls.js and console.log() to help debug animations.

Three.js Child of camera isn't visible

I'm trying to attach an object to the camera so that it can be used more more or less as a GUI element.
My camera is defined as follows:
camera = new THREE.PerspectiveCamera( 45, windowWidth / windowHeight, 1, 2000 );
camera.position.z = 100;
In my init(), I define the object to be added:
obj = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5, 1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0xFFFFFF } ));
obj.position.set( 0, 0, -50);
camera.add(obj);
But, the block does not show up. I have tried adding this object to scene, and it is visible. I added a loop to animate() that will slide the object's z position between (-50, 50), but I can't see it.
I tried using camera.lookAt(obj) and logging the world position of obj (obj position + camera position), and they behave as expected. World position seems to be what I'd expect, and camera.lookAt flips the camera when the z position crosses 0.
I apologize for not providing more clear example code, but I will do my best to cooperate with anyone trying to help me. Thanks!
Did you add the camera to the scene?
scene.add( camera );
The camera does not usually have to be added to the scene, but in this case, the object is a child of the camera, so you must.
three.js r.58

Categories

Resources