I am trying to write some sample code of three.js where i have a plane and i want that plane to rotate around.
This is my camera:
var camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(50, 50, 60);
camera.lookAt(scene.position);
and this is my plane:
var planeGeometry = new THREE.PlaneGeometry(70, 30, 1, 1);
var planeMaterial = new THREE.MeshBasicMaterial({ color: green });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
scene.add(plane);
i have other code too but this is my render and animationframe code:
renderScene();
function cameraUpdate() {
camera.position.x = cameraRadius * Math.cos(step);
camera.position.z = cameraRadius * Math.sin(step);
camera.lookAt(scene.position);
}
function renderScene() {
//make update to position, rotation of objects in the scene
step += 0.05;
cameraUpdate();
requestAnimationFrame(renderScene);
renderer.render(scene, camera);
}
My question is that inside cameraUpdate function if dont put
camera.lookAt(scene.position);
the rotation become very wierd and when i put this inside cameraUpdate, i get rotation of the plane in own axis which is desired !!!
My question is
what does scene.position mean
Why do i need to make camera lookat at every animation frame? i dont understand how its value get changed when camera is rotated
Thank you in advance !!!
If you want the plane to rotate on its own, you should just use plane.rotation.y += 0.1 on each frame, or something simple like that. What you’re doing instead is that you’re making the camera move around in circles around the plane. Think of it as walking in a circle around a coffee table. If you keep your head looking forward, you won’t see the table as you walk past it. That’s what camera.lookAt() fixes. It makes the camera look at a point in space. You can read about it in the docs.
scene.position is by default at (0, 0, 0) so it’s just another way of telling the camera to look at the center of the scene.
Related
I'm creating a game level page using three js. Here I used mapcontrols for user control. In this when I click and drag any part of the screen, the object gets translated (as per my wish). But when I move along the Z axis, the objects move along z-axis which I need to block.
I just want to make the scene like a horizontal carousel in normal html (literally)
I tried some properties of OrbitControls which is given in threejs docs.
https://threejs.org/docs/index.html#examples/en/controls/OrbitControls
Here is the code I tried
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
var mapControls = new THREE.MapControls( camera, renderer.domElement );
mapControls.enableDamping = true;
mapControls.enableRotate = false;
mapControls.enableZoom = false;
To create a carousel-like experience, you don't need orbit controls, you only need to move the camera while looking at your object is advancing through the carousel, like the typical platform games.
I have created this fiddle with an example with an sphere moving along the x axis and the camera following it.
and the relevant code is basically on the render method:
function render() {
requestAnimationFrame(render);
mesh.position.x -= 0.1;
camera.lookAt(mesh.position);
camera.position.x -= 0.1;
renderer.render(scene, camera);
}
If you want to still playing with OrbitControls and fix the axes, you need to play with minPolarAngle and maxPolarAngle, that will block vertical axis if you set the same value for both.
controls.maxPolarAngle = Math.PI / 2;
controls.minPolarAngle = Math.PI / 2;
but that gives no perspective at all, so I would use:
controls.maxPolarAngle = Math.PI / 2.2;
controls.minPolarAngle = Math.PI / 2.2;
Then you have to play with the horizontal perspective, for that you need to set minAzimuthAngle and maxAzimuthAngle between -2 PI and +2 PI...:
controls.minAzimuthAngle = -Math.PI * 1.1;
controls.maxAzimuthAngle = Math.PI * 1.1;
This will slightly turn your camera angle:
Then, using only OrbitControls you will need to move the rest of the objects in the scene, so instead of moving the sphere, you will need to move conceptually the "floor".
If this solution solves your question, please mark the answer as answer accepted, in that way it will also help other users to know it was the right solution.
I am making this program where you can click on an object, zoom to it, then look at it from all angles by holding the right mouse button and dragging. I need the camera to be going around the object, not rotate the object with the camera looking at it. I honestly just have no idea how to math it out!
For testing there is already a game object with an xyz we have selected and are looking at
var g = new GameObject(500, 0, 0);//The game object with xyz
this.selected = g;//set selected to g
//Create and set the camera
this.camera = new THREE.PerspectiveCamera(45, w/h, 1, 10000);
this.camera.position.x = 0;
this.camera.position.y = 0;
this.camera.position.z = 0;
//set camera to look at the object which is 500 away in the x direction
this.camera.lookAt(new THREE.Vector3(this.selected.x, this.selected.y, this.selected.z));
So the radius between the camera and the object is 500 and while selected and rotating, the camera should always be 500 away.
I update the scene here:
Main.prototype.update = function(){
this.renderer.render(this.scene, this.camera);//scene is just some ambient lighting
//what to do when mouse right is held down
if(this.rightMouseDown){
//placeholder functionality, needs to rotate around object based on mouse movements
this.camera.position.x -= 5;
}
}
How do I rotate this camera around g with a radius of 500?!?!
As gaitat mentioned, trackball controls are the best place to start with many configurable parameters to make camera rotation/revolution easy. One enormous potential benefit of this method ( especially for your project ) is avoiding "gimbal lock" which is the source of much frustration when working with rotations. Here's a link that might help you with Trackball controls and Orbitcontrols:
Rotate camera in Three.js with mouse
Another option would be setting camera coordinates yourself in the animation loop which is actually quite simple:
var angle = 0;
var radius = 500;
function animate() {
...
// Use Math.cos and Math.sin to set camera X and Z values based on angle.
camera.position.x = radius * Math.cos( angle );
camera.position.z = radius * Math.sin( angle );
angle += 0.01;
...
}
Another option would be to connect the camera to a pivot object and just rotate the pivot:
var camera_pivot = new THREE.Object3D()
var Y_AXIS = new THREE.Vector3( 0, 1, 0 );
scene.add( camera_pivot );
camera_pivot.add( camera );
camera.position.set( 500, 0, 0 );
camera.lookAt( camera_pivot.position );
...
camera_pivot.rotateOnAxis( Y_AXIS, 0.01 ); // radians
If you pursue this option, be aware that the camera object is in "camera pivot space", and might be more challenging to manipulate further.
I am trying out Three.js and I am trying to position a SpotLight at the position of the camera. I use the following code (stripped window creation):
$(document).ready(function() {
init();
});
function init() {
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set(50, 10, 0);
camera.lookAt(new THREE.Vector3(0, 0, 0));
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position = camera.position;
console.log(camera.position);
console.log(spotLight.position);
}
I get as output that camera.position is 50,10,0 (as expected) but spotLight.position is 0,1,0 - even tough I just set it to point at the same value?
Try
spotLight.position.set(camera.position.x, camera.position.y, camera.position.z)
position is read-only
Since SpotLight and Camera are objects (Object3D), you can simply add the spotlight to the camera. The light will be moved, rotated etc. with the camera without any further position copying. In this case you have to position the light relative to the camera:
camera.add(spotLight);
spotLight.position.set(0,0,1);
spotLight.target = camera;
I currently have a cube that I'm trying to rotate on a corner. I need it to spin on the corner like the photo below.
http://www.flickr.com/photos/fiu/2198328580/
I'm new to Three.js, so I'm sorry if this is a dumb question.
Here's the code for what I currently have
var geometry= new THREE.CubeGeometry (200,200,200, 4, 4, 4);
// material
var material = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('inc/cube.jpg'), overdraw: true
});
cube = new THREE.Mesh( geometry, material );
cube.overdraw = true;
cube.position.y = 80;
cube.position.x = 5;
cube.position.z = 6;
cube.rotation.z = 14.9;
cube.rotation.y = 0 ;
cube.rotation.x = 0 ;
scene.add(cube);
On another note.... since I have the cube.jpg texture on the cube, if I have the values for the THREE.CubeGeometry set to (200,200,200) without the 4's, the texture warps... Anyone know how to stop the warping?
This is what I'm using to render:
renderer = new THREE.CanvasRenderer();
renderer.setClearColorHex(0xffffff, 0);
renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement );
It seems to work across most browsers, but if I use the WebGL renderer, it gives me issues with the Opacity of the Canvas.
To see the Project as it stands right now, its at http://fiudevspace.com/spincube
Conceptually all you need is to rotate the cube 45 degrees on a different axis from the 45 degrees you have already rotated - I do not use THREE as it would get between me and my solution more than it helps - remember the rule of thumb on object rotations : first translate the center of the object back to the origin (if not already there) then rotate about each axis you need, then finally translate the object back into position (reverse of previous translation) - hope this helps
I have to display a rotating tetrahedron in an animated HTML5 graphic, using three.js.
When i create the object, it's upside down, but it should be on the ground with one surface, like on this screenshot: http://www10.pic-upload.de/08.10.12/v3nnz25zo65q.png
This is the code for rotating the object, at the moment. Stored in render() function. But the axis is incorrect and the object is rotating wrong.
object.useQuaternion = true;
var rotateQuaternion_ = new THREE.Quaternion();
rotateQuaternion_.setFromAxisAngle(new THREE.Vector3(0, 1, 1), 0.2 * (Math.PI / 180));
object.quaternion.multiplySelf(rotateQuaternion_);
object.quaternion.normalize();
(copied from Three.JS - how to set rotation axis)
This is the result at the moment: http://jsfiddle.net/DkhT3/
How can i access the correct axis to move/rotate the tetrahedron on the ground?
Thanks for suggestions!
Don't do what you copied. It is not correct.
I am assuming that what you want to do is to start off with a tetrahedron that is right-side-up to begin with. One thing you can do is to modify THREE.TetrahedronGeometry() to use four vertices that produce the tetrahedron that you want.
If you want to use the existing code, then what you have to do is to apply a rotation to the geometry right after it is created, like so:
const geometry = new THREE.TetrahedronGeometry( 10, 0 );
geometry.applyMatrix4( new THREE.Matrix4().makeRotationAxis( new THREE.Vector3( 1, 0, - 1 ).normalize(), Math.atan( Math.sqrt( 2 ) ) ) );
geometry.translate( 0, 10 / 3, 0 ); // optional, so it sits on the x-z plane
(Determining the proper rotation angle requires a bit of math, but it turns out to be the arctangent of the sqrt( 2 ) in this case, in radians.)
three.js r.146
Download three.js from [http://www.html5canvastutorials.com/libraries/Three.js] library and put in the below HTML code.
You will get good output.
<!Doctype html>
<html lang="eng">
<head>
<title>I like shapes</title>
<meta charset="UTF-8">
<style>
canvas{
width: 100%;
height: 100%
}
body{
background: url(mathematics.jpg);
width: 800px;
height: 500px;
}
</style>
</head>
<body>
<script src="three.js"></script>
<script>
// creating a Scene
var scene = new THREE.Scene();
// Adding Perspective Camera
// NOTE: There are 3 cameras: Orthographic, Perspective and Combined.
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
//create WebGL renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//Drawing a Tetrahedron.
var pyramidgeometry = new THREE.CylinderGeometry(0, 0.8, 4, 4, false);
//Change colour of Pyramid using Wireframe
var pyramidmaterial = new THREE.MeshBasicMaterial({wireframe: true, color: 0x0ff000});
var pyramid = new THREE.Mesh(pyramidgeometry, pyramidmaterial); //This creates the cone
pyramid.position.set(3.1,0,0);
scene.add(pyramid);
//moving camera outward of centre to Z-axis, because Cube is being created at the centre
camera.position.z = 5;
//we have a scene, a camera, a cube and a renderer.
/*A render loop essentially makes the renderer draw the scene 60 times per second.
I have used requestAnimationFrame() function.*/
var render = function() {
requestAnimationFrame(render);
/*cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
cube.rotation.z += 0.01;*/
pyramid.rotation.y += 0.01;
pyramid.rotation.x += 0.01;
pyramid.rotation.z += 0.01;
renderer.render(scene, camera);
};
// calling the function
render();
</script>
</body>
</html>