I have some days trying to make a collision for 2 objects that can detect last position before the collision happened to can make the drag for each selected object smoothly dragging without stop each time getting collide. any help to can find out the better solution ? i will be appreciate if giving a look on my code https://jsfiddle.net/minamagdy666/o1jLgv7u/102/
function onObjectChange(){
let cooldown = false; // cooldown reset when try-again clicked
let cooldown2 = false;
let objectMesh = SELECTEDOBJECT[0].children[Object.keys(SELECTEDOBJECT[0].children)[Object.keys(SELECTEDOBJECT[0].children).length - 1]];
let originPoint = SELECTEDOBJECT[0].position.clone();
if (cooldown === false) {
for (var vertexIndex = 0; vertexIndex < objectMesh.geometry.vertices.length; vertexIndex++) {
var localVertex = objectMesh.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( objectMesh.matrix );
var directionVector = globalVertex.sub( objectMesh.position );
var raycaster = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
//objects.splice(SELECTEDOBJECT[1],1);
var collisionResults = raycaster.intersectObjects( objects, true );
var collideStatus = false;
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
console.log(originPoint);
control.dragging = false;
collideStatus = true;
if(collideStatus == true){
lastPosition = originPoint;
cooldown = true;
orbit.enabled = false;
console.log(lastPosition);
}
}
}
}
}
What you want to achieve is quite tricky because of the way how TransformControls transforms objects.
A very fast way for performing collision detection tests is the usage of bounding volumes. The following fiddle shows how this can be implemented: https://jsfiddle.net/akjcpfq1/
However, when you play around with TransformControls, you will notice that objects can âpass throughâ others since the controls can perform huge translations if you move the mouse fast enough. To avoid this, you have to work with raycasting instead.
Since the object is not a single point, you need to perform raycasting from each vertex. And even this wonât give you proper results if e.g. on of the cubes is rotated by 45 degrees. The tip of one cube might pass through the other.
TBH, Iâm not sure how to approach this issue because of the way how TransformControls works.
In fact I found âTransformControlsâ great tool because its has axis to use for transforms and there is no other tool has this option.
If there is any tools that like TransformControls for Collision and has axis and can make a better result please let me know.
thank you.
Since you expect a collision response like sliding and need to test by the delta it requires a proper solver you feed with the delta/velocity, testing the scene till a velocity is found so no collisions occur anymore, returning a corrected one to slide smoothly along collided objects.
If any collision happened you could alter the transform controls delta with that. The solver can be rather simple using only bounding volumes like @Mugen87 suggested or more complex using the geometry for precise face collisions. For my engine i implemented a sphere/capsule > polygon solver which is most common for character controls, polygon > polygon is much more complicated and more expensive, ammo or a more simple physics engine could help you too on that.
Iâm really feeling stupid to ask this question but i feel that iâm so bad enough with that.
from the moment that @Mugen87 gives the solution and Iâm trying to make his solution inside the objects array that scene has many groups inside it ⌠but each time i try to done that i face a problem, and not working. sorry again for asking for help.
link: https://jsfiddle.net/minamagdy666/0o97mn6z/28/
function onObjectChange(){
SelectedAABB.copy( SelectedProductGroupBox3 ).applyMatrix4( SELECTEDOBJECT[0].matrixWorld );
//objects.splice(SELECTEDOBJECT[0],1);
for (let f = 0; f < objects.length; f++) {
AABB.copy( SelectedProductGroupBox3 ).applyMatrix4( objects[f].matrixWorld );
if ( SelectedAABB.intersectsBox( AABB[f] ) === true ) {
console.log('selected');
SELECTEDOBJECT[0].position.copy( SelectedProductGroupLastPosition );
objects[f].position.copy( ProductGroupLastPosition );
} else {
SelectedProductGroupLastPosition.copy( SELECTEDOBJECT[0].position );
ProductGroupLastPosition.copy( objects[f].position );
}
}
}
function onMouseDown(event){
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,true );
//console.log(intersects.length);
if (intersects.length > 0) {
for (var i = 0; i < objects.length; i++) {
ProductGroupBox3.setFromObject( objects[i] );
ProductGroupLastPosition.copy( objects[i].position );
if (intersects[ 0 ].object.parent === objects[ i ]) {
control.attach( intersects[0].object.parent);
SELECTEDOBJECT = [objects[ i ],i];
//SELECTEDOBJECT[0].updateMatrixWorld( true );
SelectedProductGroupBox3.setFromObject( SELECTEDOBJECT[0] );
SelectedProductGroupLastPosition.copy( SELECTEDOBJECT[0].position );
//orbit.enabled = false;
}
}
}
}
I actually didnât find.a way to solve it, if there is someone can help i appreciate. @Mugen87 solution was great but if i have many groups i have no idea how that can be handle.
I really thank you @Mugen87 for your try to help me, but i canât getting success until now, I have days on this issue and really need a help if there is any way.
thanks!