Three.js Dragcontrols move object from camera to scene - three.js

I have an cube set as child to the camera, so that when you move the camera (using OrbitControls) the cube is in a fixed position (moves with the camera)
When dragging the cube using DragControls I want to transfer the cube from the camera into the scene, so that instead of moving with the camera, the cube is a normal object with no parent and just sits in the 3D scene.
The problem is that in DragControls when you mousedown the _offset of the cube gets set before the dragstart event: https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DragControls.js#L159
So when I listen to the dragstart and then move the cube from camera to scene parent, then set the new position and updateMatrixWorld() it has no affect seeing as DragControls is remembering the old position/matrix when the click first occurred.
Here is my dragstart listener:
dragControls.addEventListener( 'dragstart', function (event) {
orbitControls.enabled = false;
if(event.object.parent.type === "OrthographicCamera") {
scene.attach(event.object);
event.object.position.set(5, 0, 0);
event.object.updateMatrixWorld();
}
} );
The current code works when you initial click the cube, but as soon as you move it (and the drag occurs the initial _offset causes the cube to ping back into an odd position.
Is there any way I can do this or would I need to modifier the DragControls module itself?

Related

Animate Camera and OrbitControls to its default position in Three.js

I have a scene with Camera and OrbitControls in position. And I'm letting users to move around the scene and change camera view and OrbitControls position.
Now I have a reset button which will reset the scene view to its default position.
We can do this using TweenJS. Just include its JS library on your web page.
Save your Camera position and OrbitControls target position when its ready to display on web like this:
const default_camera_position = { ...camera.position };
const default_controls_target = { ...controls.target };
Now in clickListener of button use this code.
createjs.Ticker.setFPS(60);
createjs.Tween.get(camera.position)
.to(default_camera_position, 500);
createjs.Tween.get(controls.target)
.to(default_controls_target, 500);
And That's all.

Animate camera horizontally three.js

I'm doing a camera animation in Three.js with GSAP, I'm trying to animate it horizontally like the panning in a film.
Anyone knows if is possible to animate the pan in orbit controls or something similar?
If you are using OrbitControls and you want to manually animate a pan, you have to animate the camera position and OrbitControls.target which represents the focus point of the controls. The relevant code for the controls is:
gsap.to( controls.target, {
duration: 2,
x: 10,
onUpdate: function() {
controls.update();
}
} );
Full demo: https://jsfiddle.net/kerpm61q/

Three.js & Dat.gui - TrackballControls renderer.domElement disables rotate and pan

I am trying to use dat.gui with a very simple three.js (r73) scene but am running into an issue with rotate and pan not working after adding "renderer.domElement" to the trackballControls initialization. Zoom works as expected.
Without renderer.domElement, I get a working rotate, zoom, pan functionality but the dat.gui interface sliders "latch" when clicked, which is just annoying and not functional. The issue as described here: Issue while using dat.GUI in a three.js example.
Looked over more info here but didn't see a great resolution: https://github.com/mrdoob/three.js/issues/828
Also found this issue. Defining the container element aka renderer.domElement doesn't work. I am unable to click within outside of the canvas area without the scene rotating.
Allow mouse control of three.js scene only when mouse is over canvas
Has anyone run into the same thing recently? If so, what workarounds are possible? Any help is appreciated.
-
The code is setup as follows:
// setup scene
// setup camera
// setup renderer
// ..
var trackballControls = new THREE.TrackballControls(camera, renderer.domElement);
trackballControls.rotateSpeed = 3.0;
trackballControls.zoomSpeed = 1.0;
trackballControls.panSpeed = 1.0;
// ..
// render loop
var clock = new THREE.Clock();
function render() {
stats.update();
var delta = clock.getDelta();
trackballControls.update(delta);
requestAnimationFrame( render );
renderer.render( scene, camera );
}
I debugged the issue with the help of this post: Three.js Restrict the mouse movement to Scene only.
Apparently, if you append the renderer.domElement child after initializing the trackballControls, it doesn't know anything about the renderer.domElement object. This also does something strange to dat.gui as described previously.
Basically, make sure this line:
document.getElementById("WebGL-output").appendChild(renderer.domElement);
appears before this line:
var trackballControls = new THREE.TrackballControls(camera, renderer.domElement);
Make sure the renderer DOM element is added to the html before it is being used as a reference.
document.body.appendChild(renderer.domElement);

three.js in,Sprite.render Depth attribute is not supported

This is my code:
var sprite = new THREE.Sprite(material);
sprite.renderDepth = 10;
The above renderDepth setting is invalid, it does not work for sprites.
How to solve this problem?
You want one sprite to always be on top.
Since SpriteMaterial does not support a user-specified renderDepth, you have to implement a work-around.
Sprites are rendered last when using WebGLRenderer.
The easiest way to do what you want is to have two scenes and two render passes, with one sprite in the second scene like so:
renderer.autoClear = false;
scene2.add( sprite2 );
then in the render loop
renderer.render( scene, camera );
renderer.clearDepth();
renderer.render( scene2, camera );
three.js r.64

How to rotate a panned object about the center using three.js?

Using three.js is it possible to rotate a panned object about its center. I have created a jsfiddle, http://jsfiddle.net/yKt6h/4/
When I checked the Auto rotate mode in the control panel, i am able to rotate the panned cube about its center. Is it possible to have a similar effect when i try to rotate the cube with mouse movement.
If it is possible please provide me sample code
I am getting an errors in the console when viewing your jsFiddle THREE is not defined However, what you are asking is not difficult. The trackball camera is designed to do exactly what you want it to. If you are rendering your object at the origin you just need to initialize the trackball controls. I created a simple moon demo that uses TrackballControls. You don't need to do any modifcation in TrackballControls.js.
In the above demo I call a function to initialize the trackball controls the function is defined in my ThreeUtil.js file as:
function initTrackball(camera, rotate, zoom, pan, damping) {
var controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = rotate || 1.0;
controls.zoomSpeed = zoom || 1.2;
controls.panSpeed = pan || 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = damping || 0.3;
return controls;
}
If you don't want the user to be able to pan or zoom, only to be able to rotate around your object, then simply set controls.noZoom = true and controls.noPan = true in the function above.
Since my moon object is at the origin of my scene all I have to do is set the camera some distance away from the origin. We will put it on the positive z axis so it is already looking at our object at the origin. Then we call the above function to set up the controls. I pass in a custom rotation speed:
controls = initTrackball(camera, 0.8);
Then in each frame all you have to do is call the update function in your anim loop:
controls.update(camera);

Resources