Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detecting collision with FirstPersonControls #1468

Closed
nathaliaspatricio opened this issue Mar 7, 2012 · 14 comments
Closed

Detecting collision with FirstPersonControls #1468

nathaliaspatricio opened this issue Mar 7, 2012 · 14 comments
Labels

Comments

@nathaliaspatricio
Copy link

My idea is to build an environment with walls and the person can not overcome them. I did the wall using cubes and I'm navigating in the scene using THREE.FirstPersonControls.

I have downloaded the files CollisionUtils.js and Collisions.js like suggested in this blog:

http://www.96methods.com/2012/01/three-js-simple-collision-detection/

Any suggestion how to do that?

@chandlerprall
Copy link
Contributor

CollisionUtils has been removed from three.js library for a while now. Update to the most recent version (r48) and look at the ray class. See this example for how to use THREE.Ray.

@nathaliaspatricio
Copy link
Author

Thanks to the example. I see that and have others questions about that.

  • Instead of use the mouse I need use the FirstPersonControls in this detection. How can I do that?
  • Is it possible to exclude some object to be intersected? I mean I have 2 objects: a cube and a plane. I want to detect the collision with cube but not with the plane. Is it possible?

@chandlerprall
Copy link
Contributor

var vector = controls.target.clone().subSelf( controls.position ).normalize();
var ray = new THREE.Ray( controls.position, vector );
var intersects = ray.intersectObject( cube );

If you have multiple, specific objects you want to intersect with:

var cubes = [ cube1, cube2, cube3 ];
var intersects = ray.intersectObjects( cubes );

@nathaliaspatricio
Copy link
Author

The code for multiple objects is working when I use the mouse detection.

But now I'm getting a error when I debug using Firebug in Firefox:

a is undefined     Three.js  (linha 13)
render()              webgl_...es.html    (linha 147)
animate()            webgl_...es.html  (linha 131)  

My render function (where is the problem according Firebug) is:

function render() {

    theta += 0.2;

    // find intersections

    var vector = controls.target.clone().subSelf( controls.position ).normalize();

    var ray = new THREE.Ray( controls.position, vector.subSelf( camera.position ).normalize() );

    var intersects = ray.intersectObject( object );

    if ( intersects.length > 0 ) {

        if ( INTERSECTED != intersects[ 0 ].object ) {

            if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );

            INTERSECTED = intersects[ 0 ].object;
            INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
            INTERSECTED.material.color.setHex( 0xff0000 );

        }

    } else {

        if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );

        INTERSECTED = null;
        delta = clock.getDelta(),
            time = clock.getElapsedTime() * 5;
        controls.update( delta );

    }

    renderer.render( scene, camera );

}

The line 147 is:

var vector = controls.target.clone().subSelf( controls.position ).normalize();

Do you know what's the problem?

@chandlerprall
Copy link
Contributor

Erm, yes. Forgot .object

 var vector = controls.target.clone().subSelf( controls.object.position ).normalize();

@nathaliaspatricio
Copy link
Author

Ok, it solved my problem here. Thanks!

Just other little problem here. Before I was using intersectScene:

var intersects = ray.intersectScene( scene );

And in the condition I was using:

if ( intersects.length > 0 && intersects[0].distance<50) {
    ....
}

Using this second condition, the camera stops and it not permitted to pass though objects. How can I do the same thing but using now intersectObjects? I have tried to understand it in the source code, but I'm newbie in javascript.

@chandlerprall
Copy link
Contributor

You need to keep a a list of the objects you want to check intersections with

var intersect_objects = [];
intersect_objects.push( obj1 );
intersect_objects.push( cube );
intersect_objects.push( cthulhu );

And then when you're doing the collision checking:

var intersects = ray.intersectObjects( intersect_objects );

@nathaliaspatricio
Copy link
Author

I'm doing that. My source code:

function render() {

    theta += 0.2;

    // find intersections

    var vector = controls.target.clone().subSelf( controls.object.position ).normalize();

    var ray = new THREE.Ray( controls.position, vector.subSelf( camera.position ).normalize() );

    var cubes = [ object, object2 ];
    var intersects = ray.intersectObjects( cubes );

    if ( intersects.length > 0 ) {

        if ( INTERSECTED != intersects[ 0 ].object ) {

            if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );

            INTERSECTED = intersects[ 0 ].object;
            INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
            INTERSECTED.material.color.setHex( 0xff0000 );

        }

    } else {

        if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );

        INTERSECTED = null;
        delta = clock.getDelta(),
            time = clock.getElapsedTime() * 5;
        controls.update( delta );

    }

    renderer.render( scene, camera );

}

My doubt is how I can use the property distance in intersectObjects to not permitting to pass though objects.

@mrdoob
Copy link
Owner

mrdoob commented Mar 9, 2012

My doubt is how I can use the property distance in intersectObjects to not permitting to pass though objects.

Didn't understand that either :S

@nathaliaspatricio
Copy link
Author

I'm doing something like a game in first person. I have some walls and the person can walk in the ambient (I use FirstPersonControls for that) but when he meet with the wall, he can't pass through it, he needs to stop the walking. The code above isn't doing that yet. There are some errors in my code, aren't there?

How can I do what I need?

@birkin169
Copy link

Did you manage to do this? Im trying to do the same.

@nathaliaspatricio
Copy link
Author

I don't manage that yet... I'm really waiting for some help...

@3DRod
Copy link

3DRod commented Mar 19, 2012

I'm also curious on how this is done.
I guess we could use the freeze property/variable declared in THREE.FirstPersonControls to make the user/camera stop moving once the ray length is smaller than a pre-defined threshold.
A control variable could be added (along with a test) to make sure we don't stop forever (getting stuck in a infinite loop) allowing the user/camera to move away from the obstacle.
The problem is I'm not very familiar with Three.js and don't really know how to code this.

@zz85
Copy link
Contributor

zz85 commented Apr 1, 2012

i think what @3DRod says about pre-defined threshold makes some sense. perhaps you could try an approach overwrite the this.onKeyDown in FPSControls. eg.

switch( event.keyCode ) {

    case 38: /*up*/
    case 87: /*W*/ 
    // Cast a ray forward. If no collisions then
    this.moveForward = true; break;

    ...

@mrdoob mrdoob closed this as completed May 5, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants