Three.js - TransformControls - javascript

I'm using the transformControls to translate, rotate and scale my objects. I want to be able to click on the different objects in my scene and transform them whenever I want: and it works !
The only problem is that geometries have their clickable zone half moved up:
That is to say that I can't select my object on clicking in the lower zone, but if I click above it will be selected.
And for the collada files it is even worse.
I think it should be somewhere here:
function onDocumentTouchStart(event){
event.preventDefault();
event.clientX = event.touches[0].clientX;
event.clientY = event.touches[0].clientY;
onDocumentMouseDown(event);
}
function onDocumentMouseDown(event){
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects);
if(intersects.length > 0){
SELECTED = intersects[ 0 ].object;
scene.add(control);
control.attach(SELECTED);
} else{
scene.remove(control);
}
}
EDIT :
OMG... The problem was some margins which were here...
But now, my beginner problem is that I don't really know how to attach transformControls to my object. With the transformControls, I still have the problem. But when I change the material color on click, it works perfectly. Have the transformControls some kind of margins ? I did this :
if(intersects.length > 0){
SELECTED = intersects[ 0 ].object;
scene.add(control);
control.attach(SELECTED);
} else{
scene.remove(control);
}

The answer was obvious... :
if(intersects.length > 0){
SELECTED = intersects[ 0 ].object;
control.attach(SELECTED);
scene.add(control);
} else{
control.detach(SELECTED);
scene.remove(control);
}
I forget to detach the controls

The answer by sRcBh is basically correct, but the code contains a mistake. The detach method of TransformControls does not take any arguments.
if (intersects.length > 0) {
SELECTED = intersects[ 0 ].object;
control.attach(SELECTED);
scene.add(control);
} else {
control.detach(); // <- THIS IS CORRECT
scene.remove(control);
}
(See https://threejs.org/docs/#examples/en/controls/TransformControls)

Related

Stop rotation on mouse hover in three.js

I have written a function by which i want to stop rotation of three.js object on mouse hover.
function onDocumentMouseUp( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.group );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if (controls.AutoRotate) {
controls.autoRotate = false;
} }
}
}
Don't know why but the function is not working neither it is giving any error in the console.Can anybody tell whats the problem over here or suggest the possible solution to this problem. Its not working maybe because i am embedding DOM elements inside three.js and using css renderer.
controls.AutoRotate does not exist so it will never be equal to true.

Picking objects with raycasters

Trying to pick some objects on click, and I'm trying to use the standard code used in every example:
function onMouseDown(evt) {
evt.preventDefault();
canvasAbsoluteHeight = $('canvas').height();
canvasAbsoluteWidth = $('canvas').width();
mouseDown = true;
mouseX = evt.offsetX == undefined ? evt.layerX : evt.offsetX;
mouseY = evt.offsetY == undefined ? evt.layerY : evt.offsetY;
var mouse = new THREE.Vector3();
mouse.x = ( evt.clientX / canvasAbsoluteWidth ) * 2 - 1;
mouse.y = 1 - ( evt.clientY / canvasAbsoluteHeight ) * 2;
mouse.z = 0;
ray = new THREE.Raycaster( mouse, camera );
var intersects = ray.intersectObjects( objects);
console.log('intersects', intersects);
if ( intersects.length > 0 ) {
console.log('intersects', intersects);
}
}
objects is an array of THREE.Object3D which should be able to be picked.
I think it may be something connected with the camera. My camera is a child of THREE.Object3D for easier manipulation, and the parent object is not set at origin.
Other thing is that canvas is not fullscreen, which may have something with mouse position? (it is inside a div with some offset from the edges of the page).
Check this fiddle. There is Picker class that you can use. First of all you have to init this class with camera and domelement
Picker.init(camera,domelement)
and then you have to attach mesh
Picker.attach(mesh)
and after that you have to specify what do you want to do after mosedown/mouseup in Picker methods.

Three.js raycaster to intersect only specified part of shape

I need to get an intersection using raycaster only with vertices of a geometry and not with all the geometry shape. I wrote this code but nothing happen if I click on vertice setted.
function onDocumentMouseClick(event) {
event.preventDefault();
mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster = projector.pickingRay(mouse2D.clone(), camera);
var intersects = raycaster.intersectObjects(objects[0].geometry.vertices[0]);// I want intersection only with vertices
if (intersects.length > 0) {
console.log("ok");}
First, you need to pass an array of objects to raycaster.intersectObjects, as suggested by pixelmike:
var intersects = raycaster.intersectObjects([objects[0]])
You can't get the vertex of the intersection per se, but you can get the face for each intersection:
for ( var i = 0; i < intersects.length; i++ ) {
if ( intersect.face == myTargetFace ) {
console.log( "ok" );
}
}
If you really want the particular object to only check for intersections with a particular subset of faces, you could override the raycast method of that object (a la https://github.com/mrdoob/three.js/blob/master/src/objects/Mesh.js#L56-L340 ) to only search those faces.
three.js r68

Reset position of SELECTED Object after clicking Three.js

I'm trying to reset the position of my latest Object in three.js.
First of all I have this:
function onDocumentMouseDown( event ) {
event.preventDefault();
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( objects );
if ( intersects.length > 0 ) {
controls.enabled = false;
SELECTED = intersects[ 0 ].object;
container.style.cursor = 'move';
//mouse Click goes here
buildMenu();
}
}
In my buildMenu Function I position my Object like this:
function buildMenu(){
camera.position.set(0,60,250);
//HERE I POSITION MY SELECTED OBJECT
SELECTED.position.x = 0;
SELECTED.position.y = 50;
SELECTED.position.z = 200;
$(document).bind('click',function(){
$(document).click(function(){
scene.remove(overlayBG);
**//HERE I TRY TO RESET EVERYTHING BUT NOTHING WORKS : (**
});
});
//$('#bg, #menu').fadeIn(100)
}
I thought I can easily reset my Object by mesh.position.set(0,0,0) inside the $(document).click Function but that doesn't work. How can I detect the latest (Re-Positioned) Object and how can I reposition it.
I'm not sure if I understood correctly.
Made a simple example, You don't need to bind any click events for this. Example is here
//last selected object
if ( SELECTED ){
SELECTED.position.set(0,0,0);
}
//new selected object
SELECTED = intersects[ 0 ].object;

Three.js project on iPhone - events issue (select&drag object )

I have building project with three.js... canvas where you can drag object
and play with the camera view as well... there is a famous example- "Draggable Cubes",
well my project is pretty similar.
On my project there are 3 main events: mouseup /mousedown/ mousemove...
Well everything was ok....but now I'm trying to run this code on iPhone,changing my events
with touchstart / touchmove / touchend...
The moving object function seems to work fine, but when I'm trying to select the object by clicking him,
it's always the same object that been selected... and not the one I'm pointing on....
I guess the problem is with this function:
function onDocumentMouseDown( event ) {
event.preventDefault();
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( objects );
if ( intersects.length > 0 ) {
SELECTED = intersects[ 0 ].object;
var intersects = ray.intersectObject( plane );
offset.copy( intersects[ 0 ].point ).subSelf( plane.position );
}
}
Is anybody have an idea what is the problem?
in this line :
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
You use the mouse Vector2 object but you don't initialize it.
Something like this should work :
mouse.x = +(event.targetTouches[0].pageX / window.innerwidth) * 2 +-1;
mouse.y = -(event.targetTouches[0].pageY / window.innerHeight) * 2 + 1;

Categories

Resources