www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: hytparadisee on June 26, 2007, 02:50:14 pm

Title: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 26, 2007, 02:50:14 pm
Generally this method works without problem. But sometimes if my camera moves too fast, it will still bump out of walls/ceilings.

I'm sure this can be solved by changing some of the values in the parameters, so what to adjust?

FYI: Im using this version:

public boolean checkCameraCollisionSpherical(int mode, float radius, float moveSpeed, boolean slideMode)
Title: Re: World.checkCameraCollisionSpherical()
Post by: EgonOlsen on June 26, 2007, 06:01:00 pm
The spherical-stuff is (unlike the ellipsoid variant) not a swept approach, i.e. it detects collisions within the sphere's radius at the end-point of the movement. It doesn't care about collisions in between, which may happen if the speed excels the radius. Try ellipsoid collision detection instead, it will cover this case.
Title: Re: World.checkCameraCollisionSpherical()
Post by: Melssj5 on June 26, 2007, 06:51:03 pm
This happens becausse the movement is more like a group of jumps than a continue movement, so if the jump if larger than the sphere diameter it wont detect the collision.

 o       |

    o    |

      o  |

       o |

        o|

         | o

maybe this can be fixed using the sphere collision detection by simulating a big jump as a set of smaller jumps.

a speed of 20f can be simulated by 10 iteration of movements of 2f on speed. checking each time the collition. This should be done for each thread iteration.
Title: Re: World.checkCameraCollisionSpherical()
Post by: EgonOlsen on June 26, 2007, 07:50:06 pm
maybe this can be fixed using the sphere collision detection by simulating a big jump as a set of smaller jumps.
Yes, i forgot about this solution. That's possible too, if spherical collision detection is needed for whatever reason.
Title: Re: World.checkCameraCollisionSpherical()
Post by: Melssj5 on June 27, 2007, 02:06:50 am
Is there any use of the sperical one instead of an ellipsoid with the same values for the 3 radius?

If not, why not to change content of the spherical to innerly use the ellipsoid ont taking the radius and setting the x, y, z and z raddios, on that way the sperical can be done using the ellipsoid.
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 27, 2007, 03:52:00 am
Actually the problem is clear, because I couldn't find an ellipsoid version where the camera can slide. I will try to increase the radius first and see if it helps.
Title: Re: World.checkCameraCollisionSpherical()
Post by: EgonOlsen on June 27, 2007, 08:41:35 am
Is there any use of the sperical one instead of an ellipsoid with the same values for the 3 radius?
Yes, the algorithm is different so that the spherical one can push you out of collisions if they've already appeared (like when two objects insects right in the beginning of the calculation). The ellipsoid approach can't do this, it's there to avoid such cases.
Title: Re: World.checkCameraCollisionSpherical()
Post by: EgonOlsen on June 27, 2007, 08:52:01 am
Actually the problem is clear, because I couldn't find an ellipsoid version where the camera can slide. I will try to increase the radius first and see if it helps.
You may have to tweak collideEllipsoidThreshold and/or recursion depth. The ellipsoid approach can slide. In fact it slides even better than the spherical approach. Have a look in the "manual" for a more detailed comparision of the two.
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 27, 2007, 12:48:45 pm
Alright, i still haven't solved the problem though, but i think i got some more understanding about the issue. My camera is not first person!!! :o. It is an orbiting camera, so when the camera orbits the object, the velocity is not around a simple axis. Then does it mean that i should use this version:

public boolean checkCameraCollisionEllipsoid(SimpleVector direction, SimpleVector ellipsoid, float moveSpeed, int recursionDepth)

Unfortunately im not specialized in maths stuff. How do I get the correct "direction" parameter, would it be camPos.calcSub(oldCamPos); ???
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 27, 2007, 12:50:25 pm
Just did the test, but the problem is that the checkCameraCollisionEllipsoid that accepts a SimpleVector as direction doesn't slide my camera. But i will stick to the SimpleVector version atm cos my camera won't go off.
Title: Re: World.checkCameraCollisionSpherical()
Post by: Melssj5 on June 27, 2007, 05:44:43 pm
Does it works for small speeds? If so, then you can use the aproach I first told, by reducing the speed on sub speeds, is not fanci and may coplicate things but is easy after all.
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 28, 2007, 06:23:48 am
Nope, it didn't work. But I think it's my problem understanding the issue (Mathematically 8)).

Take a look at this graph:
(http://peterhi.com/resources/images/20070628/slideproblem.jpg)

When the cam is orbiting and finally meet a wall, it will slide towards the target. This one is already working. But the problem is when the cam continue sliding (until it gets very close to the char), it suddenly goes to the location where my red arrow is pointing to (i.e. return to the original orbiting track).

Actually the problem is not with the collision algorithm, but with the parameters. Firstly, in this case you cannot simple use a camera constant to define the direction because the direction is always not around an axis. Secondly, I dunno how to determine the speed in this case.
Title: Re: World.checkCameraCollisionSpherical()
Post by: halcor on June 28, 2007, 09:43:42 am
Try thicker wall and/or smaller speed.
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 28, 2007, 09:52:23 am
I think in karga this one was solved pretty well, it tries to move the cam closer to the avatar and at the same time lift the camera a bit up. Is that a home-brew solution?
Title: Re: World.checkCameraCollisionSpherical()
Post by: raft on June 28, 2007, 07:09:26 pm
well, if i get you right, each frame you are moving camera starting from it's last position. the problem with this is, if camera ellipsoid is in contact with some polygons (like wall) it will get closer and closer to it each frame and at some point due to rounding errors jPCT will regard ellipsoid as slightly passed through otherside and eventually ellipsoid will pass through the wall. something similar happens when you pull down avatar for gravity each frame starting from its last position. for the gravity case, my solution is to take avatar slightly up (a safety height) then do the collision check for gravity. however this is harder for camera as there's no up direction there.

so what i do in karga for third person camera movement is: each frame i try to pull back camera from some position like avatar's head. pull back direction depends on both avatar's direction and camera's direction relative to avatar. this way if camera hits a wall it smoothly slides next to it. go next to a wall in karga in third person view and turn around, that effect is done by this

hope this helps
r a f t
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 29, 2007, 08:06:45 am
Ya that's exactly what I did, any problem with the code below ???

Code: [Select]
            SimpleVector camPos = new SimpleVector(getSpecialObject().getTransformedCenter());
            SimpleVector zOffset = getSpecialObject().getZAxis();
            SimpleVector yOffset = new SimpleVector(0, -dy, 0);
            zOffset.scalarMul(-dz);
           
            camPos.add(zOffset);
            camPos.add(yOffset);
           
            cam.setPosition(camPos);
           
            if (left) {
                world.checkCameraCollisionEllipsoid(Camera.CAMERA_MOVELEFT,
                        Util.CAM_ELLIPSOID_DIMENSION, 4, 1);
            }
            if (right) {
                world.checkCameraCollisionEllipsoid(Camera.CAMERA_MOVERIGHT,
                        Util.CAM_ELLIPSOID_DIMENSION, 4, 1);
            }
Title: Re: World.checkCameraCollisionSpherical()
Post by: EgonOlsen on June 29, 2007, 08:34:17 am
You'll never get sliding with a recursion depth of 1....
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 29, 2007, 08:57:34 am
Alright people, I still couldn't solve the problem. As I will be busy these days, i have to put it aside for a while. But i do come up with a workaround to cover up the problem (somehow, with my fuzzy head 8)). Actually sliding occurs even if the recursion is 1, but the strength is very weak (i.e. after a few units of sliding, the cam will bump out of walls). But I cannot make it too high because my camera will keep shaking when the cam gets nearer to the char. I might be wrong because my code actually comes from the car example, whereby some camera smoothing is applied. Alas, i think the problem only comes when the camera slided to a point where it gets too near to the character, so I added a threshold of my own ==> if the actual distance between cam and char after collision is less than the threshold, the camera will stop moving, so i can prevent my camera from both jumping out of my wall, and from shaking when getting too near. It works without problems, but the outcome and the effect is quite different from that in karga LOL. I will accept my way as a workaround atm, until I have more time.

But to be honest - If you have never tried the collision system in jME, you will never realize how easy you can implement collision in jPCT. Hence appreciate whatever you do in jPCT.
Title: Re: World.checkCameraCollisionSpherical()
Post by: EgonOlsen on June 29, 2007, 10:52:10 am
With a recrusion depth of 1, it will stop on the first collision in one run. The idea behind ellipsoid collision detection in jPCT is to find the first collision on the way, correct the translation vector to avoid it and move on into the new direction as long as no other collisions occur or the recursion depth has been reached. 1 will make the camera stop after the first collision. It may still slide if applied multiple times, but it won't look very smooth. Of course, collision detection can go wrong due to rounding errors, but usually, it should be possible to tweak recursion depth, Config.collideOffset and Config.collideEllipsoidThreshold to get satisfying results.
Title: Re: World.checkCameraCollisionSpherical()
Post by: raft on June 29, 2007, 01:19:44 pm
i've looked at karga code: i also use a recurse depth of 1, hence not allowing  the camera to slide. the main difference is, i dont use world.checkCameraCollisionEllipsoid(..) but world.checkCollisionEllipsoid(..) to calculate the farthest distance the camera can go, than interpolate between camera's current position and the calculated position. something like:

Code: [Select]
avatar.setVisible(false);
SimpleVector takeBackPoint = headOfAvatar();
SimpleVector moveableDistance = world.checkCollisionEllipsoid(takeBackPoint, takeBackDirection, cameraEllipsoid, 1);
avatar.setVisible(true);

SimpleVector desiredCameraPosition = new SimpleVector(takeBackPoint);
desiredCameraPosition.add(moveableDistance);
SimpleVector cameraPosition = interpolate(camera.getPosition(), desiredCameraPosition, smoothness); // 0.1is a good smoothness value
camera.setPosition(cameraPosition);
camera.lookAt(takeBackPoint);

this should feel like karga, you may add extra smoothness by interpolating camera lookAt position too

r a f t
Title: Re: World.checkCameraCollisionSpherical()
Post by: hytparadisee on June 29, 2007, 01:33:38 pm
ROFL raft, no wonder it took you soooo long to post - you are searching your source!

avatar.setVisible(false);
...
avatar.setVisible(true);

r a f t
That's tricky ;)