How determine if a chase camera is intersecting scene objects

the question says it all, how do detect geometry that the chase camera shouldn’t go through, I want the chase cam to adjust its distance from the target to compensate for objects that either gets between the camera and the target or when the cam is rotating and comes into contact with terrain and other scene objects



I’ve been looking at the collision tests for ideas and the only thing I could come up with, is having a group of rays emitting from the chaseCam location and have the chaseCam adjust its distance from target. Is that a good approach or is there something else I should do.

I hope I’m not jumping the gun with the little knowledge I have, but that’s the way I’d go about it. Fire a ray from the camera position every frame, check for an intersection. Then find the furthest intersection point, which will give you the point of contact on the obstructing object. Then I suppose you’d want to have some sort of offset from that so that your cam isn’t on that point exactly but rather a little further down the ray, or arbitrarily off the surface a certain amount. You could do that by grabbing the normal of the surface that intersection was at as well if you chose that method.



Hoping I’m not spouting bullshit XD

~FlaH

You can use the CameraNode, set it to cam->node mode and then just do collision checks with that CameraNode

normen said:
You can use the CameraNode, set it to cam->node mode and then just do collision checks with that CameraNode

:? could you elaborated......................I tried something like that and got no collision feedback whatsoever, I would have post the code, but I undid it all, after about 30mins of not gettin it to work :( maybe I screwed up the collisions checks

You have to set a BoundingVolume to the CameraNode so that it will collide.

normen said:
You have to set a BoundingVolume to the CameraNode so that it will collide.


ahh ok............well I have to go rebuild that code then and see what happens............thank man.....................will see what happens

I dont know, I’ve tried this every which but got nothing :frowning: … I duplicated some calls after repeatedly getting no result…nothing… split the terrain into its own node to test it alone as a sanity test …still nothing …reversing the collideWith() call (switching camNode and sceneNode)produces an exception and crashes -.-



what am I doing wrong,



setup

[java] camNode = new CameraNode(cam);

camNode.setModelBound(new BoundingBox());

camNode.updateModelBound();

camNode.setLocalScale(2); //tried after not getting feedback

camNode.setEnabled(true);

rootNode.attachChild(camNode);

camNode.setLocalTranslation(cam.getLocation());[/java]





update

[java]camNode.setLocalTranslation(cam.getLocation());

camNode.updateModelBound();



CollisionResults results = new CollisionResults();

camNode.collideWith(sceneNode, results);



for (int i = 0; i < results.size(); i++) {

String hit = results.getCollision(i).getGeometry().getName();

System.out.println("you hit this " + hit);

}

}[/java]

[java]camNode.setLocalTranslation(cam.getLocation());

camNode.updateModelBound();

[/java]

you dont need that, the CameraNode does that by itself, you can set the mode somehow, look at the methods

I did search, saw nothing that suggests a mode setting in cam node…and removing those lines has no effect…still no collision -.- maybe u can show an example of cam node collisions because you SEEM to suggest that outside the unneeded calls…I’m doing this correctly but…

The method is

[java]cameraNode.setControlDir(ControlDirection.CameraToSpatial);[/java]

but you’re right, the collision system doesnt support this kind of collision, so using physics collision and a GhostObject that you move with your cam seems to be the only option atm.

Hi,



I’m chasing the same goal in another thread, I think.



I didn’t yet get it to work as well and now I concentrate on other stuff first, but I will let you know, if I find a solution.



If I got it right, setLocalTranslation is not the best way to relocate stuff, if you want to register collisions, as it is more like “beaming” to a new position, rather than “moving” all the way to it.

Even if you set the Node to a spot, where its Bounds collide with the scene, it is no guaranty, that it will always work.

The distance between the old position and the new one between two updates just needs to be larger than your bounds, to make the cam pop through solids again. Means: you just need to turn your Character fast enough in 3rd person view, to run it through clips again.



My next approach will be, to attach the cam to a PhysicsCharacterNode. That way, you can really move the Node by setWalkDirection. Implementing PhysicsCollisionListener there should do the trick, to react on collisions.



Cheers



PS: Let me know once you did it, please :wink:

I dont know, your idea sounds really complicated…I still think six rays made to act like a “plain axes” emitting from the cam is a good idea…ray can have a max effect range …right :?



I’m just not very comfortable with physics camera control I just think things can get really wild especially if characters suddenly get between to camera and its target

Note the incomplete SweepSphere implementation by momoko_fan. Its based on rays I think to check collision. I did a test class with it but its not quite working, maybe someone can finish it (the SweepSphere). Right-click the SweepSphere class in the code and select “navigate to source” to see the source.

[java]

package jme3test.collision;



import com.jme3.app.SimpleApplication;

import com.jme3.bounding.BoundingSphere;

import com.jme3.collision.CollisionResults;

import com.jme3.collision.SweepSphere;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.CameraNode;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;



/**

  • Test simple collision with a sweepsphere.

    */

    public class TestCameraCollision extends SimpleApplication {



    BoundingSphere bound = new BoundingSphere(1, Vector3f.ZERO);

    CollisionResults results = new CollisionResults();

    CameraNode camNode;

    SweepSphere sphere;



    public static void main(String[] args) {

    TestCameraCollision app = new TestCameraCollision();

    AppSettings settings = new AppSettings(true);

    settings.setFrameRate(60);

    app.setSettings(settings);

    app.start();

    }



    @Override

    public void simpleInitApp() {

    sphere=new SweepSphere();

    sphere.setDimension(1, 1, 1);



    Box b = new Box(Vector3f.ZERO, 1, 1, 1);

    b.createCollisionData();

    Geometry geom = new Geometry("Box", b);

    Material mat = new Material(assetManager, "Common/MatDefs/Misc/SimpleTextured.j3md");

    mat.setTexture("m_ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));

    geom.setMaterial(mat);

    rootNode.attachChild(geom);

    }



    @Override

    public void simpleUpdate(float tpf) {

    sphere.setCenter(cam.getLocation());

    rootNode.collideWith(sphere, results);

    if(results.size()>0){

    fpsText.setText("Collision");

    }

    }

    }

    [/java]



    Edit: To avoid collision problems with the Physics solution (which looks similar) you can use collision groups or simply a GhostNode, it doesnt collide :).

I’d love to have a CollisionShape like that, to listen to collision events:



red indicating the area of sight, green the chased node.



Would provide a perfect set of collisions for my requirements.

@normen that looks like it can handle what is needed, it actually spit info out to the console, but I haven’t the slightest idea how to finish it, but I will try and see what happens will also look up the ghost node thing. …thanks