Physical interactive ChaseCamera

Hi there,



I want my ChaseCamera to be a little more intelligent. I’m trying to add functionality, that it automatically zooms in, once an object is about to get between cam position and target position.



The best would be, if I could tell it, to mind all the stuff, that was added to the bulletAppState.



I built a class, extending ChaseCamera, altering it, to my will. (ongoing)



Problem:

I neither know what approaches to registering collisions are available in this case (found two so far. Both didn’t work out yet) nor do I know, if some ways should be avoided due to heavy system load or alike.



What I tried:

1st.

Formed a Node, containing all the stuff, that is contained in the bulletAppState as well (didn’t find a way to simply ask the state for them), and ran rays by collideWith(), both in camera direction and negated direction through them.

Result:

Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

com.jme3.collision.UnsupportedCollisionException



2nd.

Tried it with rayTest() of the physicsSpace, giving cam position and direction to it, listening in the cam itself…

I’m not done with that, to see if it might work, but I’m already in doubt about it.





Am I missing out a totally different approach?

Another question is: Has no one done that before? Didn’t find anything on the net yet.



Best regards



Marrek

If your objects are physics enabled you can try using a PhyicsRigidBodyControl (old PhysicsNode) and set it to kinematic mode. It should not penetrate other physics objects when you dont set it to be completely “inside” a wall. Meaning you call setPhysicsLocation() but the attached Spatial will not be moved to that location when its inside a wall but will collide with it, the physics location is updated next tick, so you could compare that with the intended location each tick to see if there was a collision with a wall. To avoid the cam collision object to interfere with the rest of the physics you can use the collision and collidewith groups.

Thanks for the advice!



I’m at Work right now, so I can only read web material. I can’t find anything on the PhyicsRigidBodyControl. Not even on google code or google itself. Has anyone got some Docs on that?

Its the “old” PhysicsNode, otherwise the JavaDoc for the physics part is pretty complete. If theres any mentions of “PhysicsNodes” left, they are now called PhysicsRigidBody and do not extend Node anymore. The PhysicsNode is now only a wrapper for backwards compatibility and ease of use.

Hi there,



I don’t know, if I got everything the way normen tried to explain (languages…).



Here is my current state and I think, it looks promising. Doesn’t work yet anyway.



The rest of the class equals ChaseCam.



Constructor:

[java] /**

  • Constructs the physical chase camera, registers inputs and physics
  • @param cam the application camera
  • @param target the spatial to follow
  • @param inputManager the inputManager of the application to register inputs
  • @param newPhysicNodes the physicsNode, the cam shall be active in

    */

    public PhysicalChaseCamera(Camera cam, final Spatial target,

    InputManager inputManager, PhysicsSpace physicsSpace) {

    //chase cam constructor stuff

    this.target = target;

    this.cam = cam;

    initialUpVec = cam.getUp().clone();



    //giving the cam its shape

    BoxCollisionShape camShape = new BoxCollisionShape(

    new Vector3f(0.1f, 0.1f, 0.1f));

    camPhysics.setCollisionShape(camShape);

    camPhysics.setName(“camPhysics”);

    camPhysics.setCollisionGroup(1); // same is done in scene PhysicsNode

    camPhysics.setKinematic(true);



    //add PhysicsNode to world physicsSpace

    physicsSpace.addCollisionListener(this);

    physicsSpace.add(camPhysics);



    //chase cam stuff. contains: camPhysics.setPhysicsLocation(pos);

    computePosition();



    //chase cam stuff

    target.addControl(this);

    prevPos = new Vector3f(target.getWorldTranslation());

    cam.setLocation(pos);

    registerWithInput(inputManager);

    }[/java]



    And for the PhysicsCollisionListener:



    [java] public void collision(PhysicsCollisionEvent event) {

    String nodeAName = event.getNodeA().getName();

    String nodeBName = event.getNodeB().getName();

    if(nodeAName != null && nodeBName != null)

    if(nodeAName.equalsIgnoreCase(camPhysics.getName()) ||

    nodeBName.equalsIgnoreCase(camPhysics.getName()))

    System.out.println(“Hit it”);

    }[/java]



    What I do in game is smashing the Cam to the ground of the scene (I set the CollisionGroup of it the same way in its own constructor), the target is standing on. The PhysicsSpace object is the same, both for scene and cam.

    Sadly there is nothing like “Hit it” to be found in the output.



    Am I getting something of the CollisionGroup stuff wrong?

    Did I get something normen told me wrong?



    Thanks!



    [edit]

    Just noticed following line in output:

    warning CollisionDispatcher.needsCollision: static-static collision!



    I don’t get the point in the code, that prints that but it shouldn’t be connected to my Problem, as not adding the cam to PhysicsSpace doesn’t avoid the output.

I kept it very simple for now, but it works well.



I started with a copy of ChaseCamera, as extending it didn’t give me access to all the fields I needed. (Actually I didn’t check, if extending ChaseCamera would work out, with the approach I finally took.)



PhysicalChaseCamera



There is one major cutback to this solution. It probably only works with pure Nodes as a target. No CollisionShape, maybe not even a Geometry surrounding it. Didn’t try out yet.

As well, some movement configurations won’t work. I use a static position behind the Character. So you will always see the backside of it.



Anyway, hope it is a help to you!



If someone has something to commit to source optimisation, you are always welcome! I know there is potential :roll:



[edit]

Already updated the code. Removed unused field from Class… what a mucky pup I am…

1 Like

Hi there,



I got updates on this Problem. I attached a debug shape to the camPhysics that represents the camera position.

It is nicely wrapped around the point of view, as it is supposed to be. When I turn off kinematic mode, the shapes rotation clearly seems to be influenced by the physics environment.

But even though I update it’s position by setPhysicsLocation(), it moves through solid physics without hesitation. Just starts spinning as hell.



The CollisionListener is running hot with events. But I don’t get any events containing the camPhysics… Am I trying to identify the Objects the wrong way?

It should not spin when its kinematic?

It does not. I set it not to be kinematic, to check what happens. :smiley: At least that is why I am sure, that physics has impact on the Node. Shrinks the amount of possible reasons, why it doesn’t work yet.



Leaving it in default collision and collision with group, I can move other nodes through the scene with the cam. So everything works as intended this far.

I just don’t seem to receive any collision events for the one physics node, I care about…

Hm, you can also try a GhostNode and check for overlapping objects.

I tried that before, but I tried again:



I replaced the physic node with a PhysicsGhostNode (camGhost).



For the update loop:

[java]public void collide() {

CollisionResults testResults = new CollisionResults();

camGhost.collideWith(scene, testResults);

if(testResults.size() > 0)

System.out.println(testResults.size());

}[/java]



The debug shape of the camGhost is being rendered as before. It is moving (setLocalTranslation) as expected.

But no output, when I make it dive into “scene”, which is, to be honest, the PhysicsNode of the Scene.

No, you’re mixing up the two collision systems here, physics and geometry/bounding collision. camGhost.getOverlappingObjects() gives you a list of overlapping physics objects.

1 Like

Thanks!



That works, but I finally decided, to use a ray system instead, as it behaves fair enough.

marrek said:
Thanks!

That works, but I finally decided, to use a ray system instead, as it behaves fair enough.


how did you implement it, I am having the same idea, but I'm not the greatest coder so some pointers... do/s... don'ts or what ever you can offer

Cool, how about you post it in the Snippets section of the jME3 Contributions group?

Done. I talk to much :slight_smile: