I have a
function createControls(){ return new THREE.TrackballControls( camera,domElement );}
which is created with
THREE.TrackballControls=function(object, domElement){.....}
controls = createControls(camera, renderer.domElement);
restoreView(controls, vars);
addDefaultKeyEventListener();
and after resizing the webgl container the controls dont work correct..to be precise there is an event where when the user clicks on the screen a yellow ball moves to the exact place on a plain at the 3d space. After the resize event the ball moves at a spot which has a offset of that place i suppose related with the resized scale. When i try to redefine controls variable it crashes..
How can i update the controls having new camera and renderer.domElement input variables?
TrackballControls have a method for that : handleResize(). So if you create your controls with
controls=new THREE.TrackballControls(...);
You just have to add
controls.handleResize();
into the function called at the resize event.
Related
I want to add a section in one corner of my main view in which I display a small version of the main view.
I am programming a webpage using JavaScript with three.js. I have a main view window in which I display some geometries. There are rotatable and movable using OrbitControls.
In the corner of my main view I want an separate section, in which I can display a small cube, which rotates the same way my main-view rotates. But I shall not zoom in or out if I zoom the main view.
var orientationGeometry = new THREE.Mesh( geometry, material );
camera.add( orientationGeometry );
// in animate function:
orientationCube.rotation.x = controls.getPolarAngle();
orientationCube.rotation.y = controls.getAzimuthalAngle();
This rotates the small cube correctly and by adding this cube as a child to the camera it stays fixed on the screen. But when I zoom in or out this small Box as well zooms away from the camera.
Is there a way to make an extra section like shown in the attached image?
To render a second viewport on the screen you can enable WebGLRenderer.ScissorTest, set the desired scissor, scale the viewport accordingly and render the scene again. Don't forget to clearDepth() or nothing will get rendered.
Now, in order to get a different camera behavior, you need to add a second camera to the scene and update it depending on your needs. If you want it to rotate and move just like the full-screen camera, you need to update those parameters.
In order to keep a fixed zoom state, you can get the normalized position of the camera and multiply by the set distance you want to use.
function animate() {
// render full scene.
// ...
// setup scissor viewport.
renderer.clearDepth(); // important!
renderer.setScissorTest( true );
renderer.setScissor( 20, 20, insetWidth, insetHeight );
renderer.setViewport( 20, 20, insetWidth, insetHeight );
// update second camera.
camera2.position.copy( camera.position );
camera2.position.normalize().multiplyScalar( distance );
camera2.quaternion.copy( camera.quaternion );
// render small scene.
renderer.render( scene, camera2 );
renderer.setScissorTest( false );
}
Here's a working example https://jsfiddle.net/qwb39spx/
I am making an application very similar to what's on this shutterfly customization page, except more concise. I really like the preview, but I need guidance on how to rotate the object the way they do in their preview. Currently, I'm using THREE.OrbitControls(), but my object rolls out of view and the camera isn't focused on the actual object. I tried focusing on the object, but I get an error.
Edited to add: My object is a .ply file so I'm using PLYLoader.
I found this other perfect example of what I want to do that uses mouse events: https://jsfiddle.net/n6u6asza/1735/
It's clever, but I want to use three.js libraries instead of these mouse events because my object keeps disappearing when I remove the controls and if I can keep my code shorter, that'd be ideal. I've spent several hours reading about OrbitControls(), but nothing I've tried has kept the object focused so it seems I'm only rotating the object.
The control code:
controls = new THREE.OrbitControls( camera, renderer.domElement);
controls.minPolarAngle = toRadians(0); //was trying to limit the object
controls.maxPolarAngle = toRadians(45); //movement with these
controls.enablePan = false;
controls.enableZoom = false;
//controls.enabled = false;
controls.update();
I also have a basic animate function. I want to later implement auto rotate as a button option.
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
Just to recap, my question is:
How do I keep focus on an object when rotating the camera?
OR
How do I rotate the object without moving the camera?
Edited to add my object code:
var loader = new THREE.PLYLoader();
loader.load( 'sleeve.ply', function ( geometry ) {
geometry.computeVertexNormals();
var material = new THREE.MeshStandardMaterial( { color: 0xffffff } );
sleeve = new THREE.Mesh( geometry, material );
scene.add( sleeve );
});
To keep focus on an object you should use https://threejs.org/docs/#api/en/core/Object3D.lookAt
object.lookAt(x,y,z) or object.lookAt(vector);
For controls you should change the target https://threejs.org/docs/#examples/controls/OrbitControls.target
controls.target = object;
Or you can modify transform controls, if you want to rotate object and not rotate camera around object.
https://threejs.org/examples/?q=control#misc_controls_transform
I would like to display, after clicking on an image illustrating a Three.js scene, this Three.js scene and be able to run it. Once one has clicked on image, I would like to include Three.js scene into a frame with a grey background (like lightbox does with images)
Here's below an example of what I would like to get :
You can see this WebGL scene on the following link :
Three.js scene
As you can see, this scene fills the entire window of browser.
If someone could give me some clues to acheive this, it would be nice.
Thanks
Include your image with classic html.
Include an empty div with a known id with classic html.
Add an event listener to execute a function (eg. init()) when somebody clicks the image.
This init function should init the THREE.WebGLRenderer, the THREE.Scene, render() etc.
The function should then add the element in the empty div with : document.getElementById("empty-div").appendChild(this.renderer.domElement);
To make it seem like a frame, you should then toggle CSS class. Do you know how to make such a frame in CSS ?
Eventually, to update the size of the Three Scene when the user resizes the window, you can add window.addEventListener('resize', resizeFunction, false); and the resizeFunction should use window.innerWidth and window.innerHeight to execute renderer.setSize(width, height);
Three.js version: r79
Basically, I want to have a 3D object (a mesh created with THREE.TextGeometry) act like it's in 2D space but is always in the same exact place on the screen (never moves with the camera, no matter if I zoom or pan). Is there a way to do this?
I'm actually not quite sure how unless I make what I feel is a giant hack and update the coordinates of the text mesh every time there is a mouse scroll event or pan event.
One solution is to add the mesh as a child of the camera.
scene.add( camera ); // required, since the camera has a child
camera.add( mesh );
mesh.position.set( 0, 0, - 100 ); // or whatever
three.js r.79
I'm using TrackballControls to rotate the camera in my scene using the mouse but also need to be able to rotate individual objects in the scene using the mouse. I'd like to be able to toggle on/off TrackballControls to accomplish this. However, so far there are issues with everything I've tried. This is how my controls are defined:
var controls; // global
inside init():
controls = new THREE.TrackballControls( camera );
controls.addEventListener( 'change', render );
and finally in animate():
controls.update();
So far, I've tried:
Removing the event listener like this: controls.removeEventListener( 'change', render ); which didn't change anything; controls worked the same as it always has.
Conditionally updating the controls like this:
(global)
var enableControls = true;
(in animate)
if (enableControls == true) {
controls.update();
}
and then toggling enableControls using a KeyDown event. This seemed to work, because when enableControls was false I could rotate an object without moving the camera. However, when I update again, the camera moves significantly (it moves to where it would have been based on my clicking/dragging done while I wasn't updating).
I tried both of these separately and in conjunction with one another with no luck.
To disable TrackballControls, all you need to do is set
controls.enabled = false;
Also, you likely do not need controls.addEventListener( 'change', render ); since you are calling controls.update() in the animation loop.
three.js r.67