Physics, and how it applies to vehicles

Get technical support about the C++ source code and about Lua scripts for maps, entities, GUIs, the console, materials, etc. Also covered are the Cafu libraries and APIs, as well as compiling, linking, and the build system.
Post Reply
minosdis
Posts:24
Joined:2008-08-09, 05:42
Physics, and how it applies to vehicles

Post by minosdis » 2008-08-14, 05:19

So, after going through the physics implementation for a little bit, there are a few questions I had, and things I wanted to discuss. I noticed a few assumptions you made; most seem benign, like assuming the wind resistance, constant acceleration from gravity, etc. However, there were a few that would need to be addressed for vehicles.
First off, friction. The friction is model is fairly simple, which is perfectly fine for human movement. You define it,

Code: Select all

    const double GroundFriction=4.0;
    const double AirFriction   =0.2;
Then implement it,

Code: Select all

    switch (PosCat)
    {
        case InAir  : Drop=CurrentSpeed*AirFriction*FrameTime;  // This is a very rough approximation. 
                      break;                                    // We might need a new models for deceleration due to air resistance (aircraft)
        case OnSolid: double Control=CurrentSpeed<StopSpeed ? StopSpeed : CurrentSpeed;
                      Drop          =Control*GroundFriction*FrameTime; // Again, a rough approximation. 
					  // Friction increase with velocity, also depends on both surfaces. need new model
                      // To do: if the leading edge of the BB is over a dropoff, increase friction
                      break;
    }
AirFriction, or air resistance isn't really a big deal, even for aircraft unless you writing a simulation. No big deal there, but ground friction for vehicles is a big deal. Most importantly, it varies greatly with the characteristics of the two materials (Coefficient of Friction). A check could be done here to the contacting brush below. For instance, roads could be attached to entities having a flag for road, or dirt, etc. Anything else (so the entire map doesn't need to be flagged) could be assumed to be dirt (or any defined material, preferably by the map, not hardcoded). Secondly, friction depends greatly on the mass of the object. This is easily dealt with by a new variable in the vehicle's entity. Friction is also dependant on a number of other factors, but these are more or less negligable to mass (normal force), and the coeffecient of friction between the two surfaces. I suppose one could also take rolling friction into consideration also, not sure how that would compare with kinetic friction though.

Next, a random bit of code I didn't quite understand.

Code: Select all

// Permittivity of free space?  Not really.. If the WishSpeed is that small, why not just set it to 0?
    if (WishSpeed>0.001 /*Epsilon*/) WishDir=scale(WishVelocity, 1.0/WishSpeed);
Wasn't really sure whats going on here.

Probably my biggest question is this. It seems as though when the player makes a movement command, he is really setting the WishVelocity, saying I want to move in this direction at this speed. Which is fine for humans, but for vehicles it's a little backwards. Vehicles think more along the lines of, I want to apply this much torque, or this large of an impulse. Code wise, is there a way to change this? The only way I can see right now would be something like this;
If a player is in a vehicle, he has a flag saying so.
If the flag is up, ApplyAcceleration() catches it, and rather then using predetermined values, calculates what the acceleration *should* be. It then simply applies this acceleration to the current velocity (after accounting for air resistance, friction, etc) , ignoring WishVelocity.

Which brings up another question.

Code: Select all

    switch (PosCat)
    {
        case InAir  : // airborn, so little effect on velocity - Will change for aircraft
                      Acceleration=AirAcceleration;
                      AddSpeed=WishSpeed>500.0 ? 500.0-CurrentSpeed : WishSpeed-CurrentSpeed;
This seems to be creating a sort of asymptote towards terminal velocity at 500. (note: 500 what? I saw earlier gravitation acceleration being 9810.0, so 500 is 0.5 meters per second?) This would certainly need to be removed (at least in the XY plane) for aircraft. Seems a little low for terminal velocity also. To fully solve this equation we would need to consider a few things. First, the mass. easy. Second the projected surface area of the falling object. This could be easy. Seeing as all the objects already have a bounding box, we might be able to quickly calculate the surface area. Coefficient of drag. This depends on so many things, its not even worth trying to find. Easiest just to set it to one. Lastly density of the fluid (air). Technically, this varies with altitude, but unless someone is making a high altitude sky diving simulation, I think we could safely assume this to be constant. Its about 1.2.
So, we started with this equation;
v = sqrt(2mg / ?AC) (latex would be nice on these boards ;)
now we have this:
v = sqrt(19.6m/ 1.2A)
substitute in the above code:

Code: Select all

TerminalSpeed = sqrt( (19.6 * GameWorld->GetBaseEntityByID(EntityId).Mass) / (1.2 * GameWorld->GetBaseEntityByID(EntityId).GetXYArea() ) )
AddSpeed = WishSpeed > TerminalSpeed ? TerminalSpeed - CurrentSpeed : WishSpeed-CurrentSpeed;
Note I created a new function in the entity to calculate the XY plane area of the bounding box:

Code: Select all

Vector3T<float> *Corners[8];
Vector3T<float> *Plane[4];
Vector3T<float> *a, *b;
float ret;
State.Dimensions.GetCornerVertices(Corners); // Not Sure how these will be ordered.
Plane[0] = Corners[0]; // Start us off
for (int i = 1; i < 8; i++;) { // We will find the 4 lowest corners
    for (int j = 0; j < 4; j++;) if (Corners[i].z < Plane[j]) Plane[j] = Corners[i];
}
a = Plane[0];  // Use this corner as a starting points
for (int h = 1; h < 4; h++)  {
if (Plane[i].x != a.x &&  Plane[i].y != a.y) b = Plane[i]; // this should give us two opposite corners
ret = abs(a.x - b.x) * abs(a.y - b.y);
return ret;
Really not sure if that will work or not, but it shows finding a *rough* projected area isn't terribly difficult.
However, it could also be used to implement a simplified drag equation, Fd = 0.5 ? v^2 Cd A, again assuming Cd to be 1 and ? (density of air) to be 1.

Well I think thats quite a bit of rambling for one night. More or less just some thoughts on how to make the physics model more inclusive without over complicating things. I'm going to do a little bit more thinking, and post my ideas on steering. Scratch that, a lot more thinking, thats a tough subject ;)
minosdis
Posts:24
Joined:2008-08-09, 05:42

Re: Physics, and how it applies to vehicles

Post by minosdis » 2008-08-14, 05:49

So after thinking for a little bit I came up with this; Calculating the physics surrounding a vehicle (lets start with a car), can be pretty tough if we try to generalize the overall movement and forces. While thats generally the easiest route to take, in this case there are so many variables involved it becomes tough to generalize without losing the expected behavior of a car. So instead, What if we start with the tires.
Looking at each tire individually, we know that its rotating around an specific axis at a certain angular velocity. Assuming we know the material beneath the tire, and thereby the coefficient of friction. Sort of. Firstly we have to decide, is the tire rolling, or is it skidding? To find this out, we compare the angular velocity and the circumference of the tire (which tells us how fast the tire *should* be travelling) with how fast along the direction of the tire's rotation its actually moving. This tells us if the tire is skidding, spinning out or travelling normally. You notice I specified above, along the direction of the tire's rotation. This is key, because while the tire may be rotating at the correct angular velocity for it's linear velocity along that axis, if its sliding along another axis there will be a different friction. Under normal movement, there will be a static friction, because essentially the part of the tire touching the road is, at that moment, not moving in relation to the road. However, if the tire is sliding off in a different direction, its now moving, so we have kinetic friction. Kinetic friction is always less then static, and I would imagine this phenomenon will have a good deal of impact on the belivability of the car's behavior.
So okay, we know what the forces of friction are on the tire. A little out of order, we probably should have applied the force from the engine first. So lets say we did. Now we know that too. Thats pretty much it. Do that for each tire, and we now know 4 force vectors. Apply these vectors to the car's origin vector and we should have a fairly decent approximation of a car. Of course along the way we would need to account for things like changes in hieght of the surface below the tire (to raise it, nobody likes static looking wheels), if the tires are in the air (can't accelerate mid-air...) but this is the general idea.
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Physics, and how it applies to vehicles

Post by Carsten » 2008-08-14, 13:47

Dear MinosDis,

first of all, thank you very much for your wonderful review at http://www.devmaster.net/engines/engine ... .php?id=31
It's really great to get reviews like that! :wohow:

About the player physics code:
You should generally know that the physics code in the DeathMatch MOD is among the oldest pieces of code in the entire Ca3DE code base (generally speaking, many parts of the DeathMatch code are pretty old; the newer Ca3DE subsystems are better designed and better documented etc.).
minosdis wrote:However, there were a few that would need to be addressed for vehicles.
First off, friction. The friction is model is fairly simple, which is perfectly fine for human movement.
Yes, it was made to meet the minimal requirements - human movement. At the time it was written, nobody thought about vehicles (at least in 3D games ;) ).
AirFriction, or air resistance isn't really a big deal, even for aircraft unless you writing a simulation. No big deal there, but ground friction for vehicles is a big deal. Most importantly, it varies greatly with the characteristics of the two materials (Coefficient of Friction). A check could be done here to the contacting brush below. For instance, roads could be attached to entities having a flag for road, or dirt, etc. Anything else (so the entire map doesn't need to be flagged) could be assumed to be dirt (or any defined material, preferably by the map, not hardcoded). Secondly, friction depends greatly on the mass of the object. This is easily dealt with by a new variable in the vehicle's entity. Friction is also dependant on a number of other factors, but these are more or less negligable to mass (normal force), and the coeffecient of friction between the two surfaces. I suppose one could also take rolling friction into consideration also, not sure how that would compare with kinetic friction though.
Agreed, this is a nice summary of the situation.
Taking various friction coefficients into account would be possible either as a property of the material on the current surface, or by defining volume brushes and testing for volume intersection. The latter would also work for bodies of water, swamps, etc.
Next, a random bit of code I didn't quite understand.

Code: Select all

// Permittivity of free space?  Not really.. If the WishSpeed is that small, why not just set it to 0?
    if (WishSpeed>0.001 /*Epsilon*/) WishDir=scale(WishVelocity, 1.0/WishSpeed);
Wasn't really sure whats going on here.
WishDir is computed as the unit vector of WishVelocity, with an additional test to avoid division-by-zero conditions. In newer code, the same line would read

Code: Select all

const VectorT WishDir=normalizeOr0(WishVelocity, 0.001);
Probably my biggest question is this. It seems as though when the player makes a movement command, he is really setting the WishVelocity, saying I want to move in this direction at this speed. Which is fine for humans, but for vehicles it's a little backwards. Vehicles think more along the lines of, I want to apply this much torque, or this large of an impulse. Code wise, is there a way to change this? The only way I can see right now would be something like this;
If a player is in a vehicle, he has a flag saying so.
If the flag is up, ApplyAcceleration() catches it, and rather then using predetermined values, calculates what the acceleration *should* be. It then simply applies this acceleration to the current velocity (after accounting for air resistance, friction, etc) , ignoring WishVelocity.
Yes, I think that's the proper strategy: You could "copy" all the physics code, then modify the copy to implement vehicle physics just as you like it. The player would keep a flag that decides whether the human or the vehicle physics code is called (when the player is implemented with the State pattern, things remain the same but become a bit more elegant and more clearly separated).
Which brings up another question.

Code: Select all

    switch (PosCat)
    {
        case InAir  : // airborn, so little effect on velocity - Will change for aircraft
                      Acceleration=AirAcceleration;
                      AddSpeed=WishSpeed>500.0 ? 500.0-CurrentSpeed : WishSpeed-CurrentSpeed;
This seems to be creating a sort of asymptote towards terminal velocity at 500. (note: 500 what? I saw earlier gravitation acceleration being 9810.0, so 500 is 0.5 meters per second?) This would certainly need to be removed (at least in the XY plane) for aircraft. Seems a little low for terminal velocity also.
For understanding this, it is better to consider case OnSolid first, case InAir plays tricks with the 500 number: The function computes the CurrentSpeed a few lines earlier, which expresses how much of the players current velocity (kept in State.Velocity) is already into the direction of WishDir/WishVelocity.
Case OnSolid then computes AddSpeed, which is how much speed is missing from CurrentSpeed in order to obtain WishSpeed.
AddSpeed is then used below the switch (PosCat) statement in order to limit the actually computed change in speed.

Back to case InAir: Here we artificially limit/clamp to a max. speed of 0.5 meters per second. (Yes, the base unit in Ca3DE is millimeters, a somewhat unfortunate choice that I made more than 10 years ago. I've plans to change the base units to meters though in one of the upcoming revisions. This will be done in a backwards-compatible manner.)
The reason for the clamp is that players cannot accelerate on their own (contrary e.g. to being force-pushed by an explosion) to more than 0.5 m/s in free fall. (But this leaves them some control even when airborne.)
To fully solve this equation we would need to consider a few things. First, the mass. easy. Second the projected surface area of the falling object. This could be easy. Seeing as all the objects already have a bounding box, we might be able to quickly calculate the surface area. Coefficient of drag. This depends on so many things, its not even worth trying to find. Easiest just to set it to one. Lastly density of the fluid (air). Technically, this varies with altitude, but unless someone is making a high altitude sky diving simulation, I think we could safely assume this to be constant. Its about 1.2.
So, we started with this equation;
v = sqrt(2mg / ?AC) (latex would be nice on these boards ;)
now we have this:
v = sqrt(19.6m/ 1.2A)
substitute in the above code:

Code: Select all

TerminalSpeed = sqrt( (19.6 * GameWorld->GetBaseEntityByID(EntityId).Mass) / (1.2 * GameWorld->GetBaseEntityByID(EntityId).GetXYArea() ) )
AddSpeed = WishSpeed > TerminalSpeed ? TerminalSpeed - CurrentSpeed : WishSpeed-CurrentSpeed;
Sounds good! :-)
Note I created a new function in the entity to calculate the XY plane area of the bounding box:

Code: Select all

Vector3T<float> *Corners[8];
Vector3T<float> *Plane[4];
Vector3T<float> *a, *b;
float ret;
State.Dimensions.GetCornerVertices(Corners); // Not Sure how these will be ordered.
Plane[0] = Corners[0]; // Start us off
for (int i = 1; i < 8; i++;) { // We will find the 4 lowest corners
    for (int j = 0; j < 4; j++;) if (Corners[i].z < Plane[j]) Plane[j] = Corners[i];
}
a = Plane[0];  // Use this corner as a starting points
for (int h = 1; h < 4; h++)  {
if (Plane[i].x != a.x &&  Plane[i].y != a.y) b = Plane[i]; // this should give us two opposite corners
ret = abs(a.x - b.x) * abs(a.y - b.y);
return ret;
Really not sure if that will work or not, but it shows finding a *rough* projected area isn't terribly difficult.
However, it could also be used to implement a simplified drag equation, Fd = 0.5 ? v^2 Cd A, again assuming Cd to be 1 and ? (density of air) to be 1.
You can simplify the above method somewhat:

Code: Select all

const Vector3fT Diagonal=State.Dimensions.Max-State.Dimensions.Min;    // Just ignore the .z component.
return Diagonal.x*Diagonal.y;
Well I think thats quite a bit of rambling for one night. More or less just some thoughts on how to make the physics model more inclusive without over complicating things. I'm going to do a little bit more thinking, and post my ideas on steering. Scratch that, a lot more thinking, thats a tough subject ;)
:cheesy: :up:
Best regards,
Carsten
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Physics, and how it applies to vehicles

Post by Carsten » 2008-08-14, 14:15

minosdis wrote:So after thinking for a little bit I came up with this; Calculating the physics surrounding a vehicle (lets start with a car), can be pretty tough if we try to generalize the overall movement and forces. While thats generally the easiest route to take, in this case there are so many variables involved it becomes tough to generalize without losing the expected behavior of a car. So instead, What if we start with the tires.
Looking at each tire individually, [...]
While I basically agree with your thoughts, but this reminds me of something that I forgot to mention in my above post: Accurate physics simulation and "believable and felt behavior" is not necessarily the same.
I say this because in the history of the human player physics code I frequently got some complaints about it: They essentially all said that the player controls feel like gliding on ice, and the jumps feel like we have reduced gravity as on the moon.

While I must admit that forward/backward motion was essentially just tweaked until both the acceleration constants and the resulting observed behavior approximately felt right, it could have been fixed e.g. by increasing the numbers for the friction.
But I also spent considerable amounts of time with checking the equations for jumping. While I was (and still am) sure that they are physically correct and the constants are right, too, it still feels like on moon.
I think that the reason for this is that a player jump is more than one meter(!) high - an action that I doubt can anybody do in the real world without bending the knees first, etc.. Even if you could, a fall from 1m height is normally softened by bending the knees somewhat on touchdown, then back to normal standing position again.

In summary, if everyone could jump more than 1m upwards, without bending the knees for acceleration first, also the real jumps would feel like the simulation in Ca3DE. But we cannot (easily), and so people complain about "wrong" physics.

Back to cars, as a result from the earlier experiences with player movement code, I would probably not try to make a very accurate simulation right from the start. Maybe I'd just try to tweak some of the constants of the human physics code initially. A second step would be to implement some movement of the tires (for simulating the springs), but I'd do that just for visual effects, not as a component of physics simulation.
I guess that this, together with a car model and proper HUD, sounds, etc., already yields a realistic driving simulation through a map.
Personally, only then would I implement a more realistic driving and physics simulation.

On the other hand, I must admit that my physics knowledge became a bit rusty over the years. Maybe if you see room for improvements right in step 1 - why not? ;)
Best regards,
Carsten
minosdis
Posts:24
Joined:2008-08-09, 05:42

Re: Physics, and how it applies to vehicles

Post by minosdis » 2008-08-15, 02:52

So i've got a lot of the basic framework for a vehicle worked out, with some of the individual methods done. Currently, I'm stuck on this. the vehicle class has a method called UpdatePassengerVelocty(), which recieves a few things, mainly State, WishAcceleration, WishDir and PositionIndex (which seat the player is in). Heres my delema: Consider the top-down view of a car turning. Okay, in a usual, controlled turn the center of rotation would be between the two rear wheels. If this is the case, then the player's movement vector would look alot like a torque, only in reverse. However, in this method, we can't assume we are in a controlled turn. We could be moving straight, could be sliding sideways, shoot we could have just been hit by a truck and flipping end over end. So this means the center of rotation is not static. What do you think would be a good way of finding the (3 dimensional) center of rotation? I'm stumped....
EDIT:
This isn't true. The center of rotation would actually be quite far outside of the vehicle (imagine a freeway onramp, the center of rotation is somewhere near the middle of the loop..) Still doesn't help, as this is clearly the wrong way to go about it.


EDIT:
After pluggin away at this for a few days, I'm starting to wonder, would it be easier to implement a true physics SDK into the Ca3D engine? I know that would be a major change / addition to the engine, but structurally, I think it might not be too hard. Most of the physics sdks I've played around with (PhysX, Newton, and ODE) operate in a very similar way to Ca3D. anyway, just an idea
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Physics, and how it applies to vehicles

Post by Carsten » 2008-08-15, 09:30

minosdis wrote:[...] The center of rotation would actually be quite far outside of the vehicle (imagine a freeway onramp, the center of rotation is somewhere near the middle of the loop..) Still doesn't help, as this is clearly the wrong way to go about it.
I think what you need are transformation matrices: Normally, there is one matrix for each entity that describes the position and orientation of the entity in world space. (In the code, this matrix might not be explicitly written out, but it can easily be found by the State parameters like Origin and Angles).
That is, there is a matrix for the vehicle and (normally) a matrix for the player that position their entity in world space. I normally call these matrices "model-to-world" (M2W) matrixes, because they transform coordinates from model (entity) space into world space.
Now, when the player enters a vehicle, its matrix no longer positions him wrt. world space, but wrt. vehicle space. That is, this matrix describes the players offset wrt. the vehicle origin when the player is seated in the vehicle. You could call such a matrix "player-to-vehicle" (P2V), because it transforms coordinates from player space into vehicle space. The players position in world space would then be found by the product of the M2W and P2V matrices.

This way, you could move the vehicle freely and arbitrarily, and know the players world space position and orientation at all times. Most force and velocity vectors had to undergo the same matrix transformation (or the inverse for the "other direction") during the computations.
After pluggin away at this for a few days, I'm starting to wonder, would it be easier to implement a true physics SDK into the Ca3D engine? I know that would be a major change / addition to the engine, but structurally, I think it might not be too hard. Most of the physics sdks I've played around with (PhysX, Newton, and ODE) operate in a very similar way to Ca3D. anyway, just an idea
WOW, I'd absolute LOVE doing this!!! :wohow:
Afaik, both the big physics SDKs (PhysX and Havok) underwent big political changes recently, so there would be the question which one to pick, especially since there are of course also the alternatives like Newton and ODE (and Bullet) you mentioned.
Anyways, I'd be very happy about and much support adding "true" physics support to the game code!!
Best regards,
Carsten
minosdis
Posts:24
Joined:2008-08-09, 05:42

Re: Physics, and how it applies to vehicles

Post by minosdis » 2008-08-18, 06:55

So after comparing most of the different physics engines I've come to a bit of a conclusion. I'm thinking PhysX would probably be the best solution, because first and foremost it is FAST. Not to mention it is the only physics engine to support physics cards (including GeForce cards Also, the features compared to all the other engines are out of this world, it really has every thing we need; Character Control, Convex Hulls, Soft bodys, vehicles, cloth, the list goes on... It is also very well documented, which is a big plus.
As far as implementation goes, I think your right. We should be able to find a way to get this done in just the game code. From my understanding, here how most physics engines work (physx included). First, create the physics world, define a few parameters like gravity and mass. Then add each physics object to a scene, defining things like collision mesh (could be a bounding box, or any number of primatives including convex mesh), and mass. Some engines want more info about the objects like Moments of Inertia, density, etc. Not sure about PhysX yet. Then every frame, send a call to the physics engine's update, with the timestep. Lastly, update all the physics' objects positions in the game world. (Then release all the physics objects and world of course). The game world would probably be best created in either the GameT or the GameImplT classes. Now heres a tricky thing. Originally I figured physics objects would be created in the BaseEntityT class, that way we wouldn't have to go through every single entity we wanted to exist in the physics world and add code to the constructor. But, then I realized, adding something to the BaseEntityT constructor is futile because all the derived classes wont use anything from BaseEntityT's constructor. duh. So I'm not sure here, we might just want to add code to all the objects present in physics, but thats not a very agile solution. So I'm not really sure here. Theres probably some nice, simple OO solution here that I don't know about yet. But ideally, this would be done in BaseEntityT, that way any new entities could simply include a line of like AddtoPhysicsWorld(colMesh, Mass, etc); Actually, thats a pretty good solution, just add a method to baseentity. Ok, so lastly the update function. Here I really don' know. It just needs to be called reliably every frame. I don't know enough about the prediction being done to say if clients should predict this or not, and if the actual calculations should be done on the server or client. I think I'll leave this part up to you. :P

So anyways, to make a long story short, I think you're right, this should be able to be done in the game code, and might not be too tough.
minosdis
Posts:24
Joined:2008-08-09, 05:42

Re: Physics, and how it applies to vehicles

Post by minosdis » 2008-08-19, 17:44

Some interesting threads here pertaining to an issue that will certainly need consideration, the timestep and game loop.

Fixed TimeSteps
http://developer.nvidia.com/forums/inde ... topic=2017

Decoupling physics and display in a game loop
http://developer.nvidia.com/forums/inde ... topic=1815

I don't really know much on the actual game loop in Ca3D, but it seems like the prevailing method with PhysX is to update the physics world at 60Hz regardless of the rendering frequency (aka Frames per Second). I'm not sure about how this is done exactly, perhaps using a seperate thread for physx would be a good way? That way, no matter what framerate your getting the physics would still be deterministic.
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Physics, and how it applies to vehicles

Post by Carsten » 2008-08-19, 22:03

Hi MinosDis,
minosdis wrote:So after comparing most of the different physics engines I've come to a bit of a conclusion. I'm thinking PhysX would probably be the best solution, because first and foremost it is FAST. Not to mention it is the only physics engine to support physics cards (including GeForce cards Also, the features compared to all the other engines are out of this world, it really has every thing we need; Character Control, Convex Hulls, Soft bodys, vehicles, cloth, the list goes on... It is also very well documented, which is a big plus.
Ok, thanks for pointing these items out! I'll look into PhysX over the next few days. :up:
Another important factor will be easy of use and ease of shipping (i.e. the end-user must not be burdened with a difficult installation), but I'll look at that, too.
As far as implementation goes, I think your right. We should be able to find a way to get this done in just the game code. From my understanding, here how most physics engines work (physx included). First, create the physics world, define a few parameters like gravity and mass. Then add each physics object to a scene, defining things like collision mesh (could be a bounding box, or any number of primatives including convex mesh), and mass. Some engines want more info about the objects like Moments of Inertia, density, etc. Not sure about PhysX yet. Then every frame, send a call to the physics engine's update, with the timestep. Lastly, update all the physics' objects positions in the game world. (Then release all the physics objects and world of course). The game world would probably be best created in either the GameT or the GameImplT classes.
Right, great overview of the overall process. I've never looked in-depth into a Physics API, but I agree that it will and should likely work like this.
Now heres a tricky thing. Originally I figured physics objects would be created in the BaseEntityT class, that way we wouldn't have to go through every single entity we wanted to exist in the physics world and add code to the constructor. But, then I realized, adding something to the BaseEntityT constructor is futile because all the derived classes wont use anything from BaseEntityT's constructor. duh. So I'm not sure here, we might just want to add code to all the objects present in physics, but thats not a very agile solution. So I'm not really sure here. Theres probably some nice, simple OO solution here that I don't know about yet. But ideally, this would be done in BaseEntityT, that way any new entities could simply include a line of like AddtoPhysicsWorld(colMesh, Mass, etc); Actually, thats a pretty good solution, just add a method to baseentity.
Yep!! :up: I'm not much worried about this: once we have chosen an API and gained sufficient understanding of its use, things like these will fall into place just naturally.
Ok, so lastly the update function. Here I really don' know. It just needs to be called reliably every frame. I don't know enough about the prediction being done to say if clients should predict this or not, and if the actual calculations should be done on the server or client. I think I'll leave this part up to you. :P
I guess that it depends. Actually, we have two sorts of physics: Such that is eye-candy only, and such that is relevant for the gameplay.
That that is eye-candy will only run on the client. It will not affect gameplay, and other players might never even see it. Examples would be flying debris, smoke, etc.

"Relevant" physics like falling bridges, elevators etc. must be run on the server. Like any other NPC entity, they cannot be predicted, but it might be desireable to "mix" them, e.g. when a bridge breaks and falls, the main pieces must be run on the server, flying debris can be run on the clients.
Best regards,
Carsten
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Physics, and how it applies to vehicles

Post by Carsten » 2008-08-19, 22:19

minosdis wrote:[...] I'm not sure about how this is done exactly, perhaps using a seperate thread for physx would be a good way? That way, no matter what framerate your getting the physics would still be deterministic.
Well... I understand the issue technically, but I don't see a big problem. Maybe the most important consideration is that a fixed framerate for the physics makes things indeed "more deterministic" - with varying framerates there can be small differences in runs with different framerates.
It's also a question on how frequently you sample player input and how frequently it is sent to the server, and on the details how the server computed the new player entity state from the input.

However, let's separate the physics again into client-side-only and server-side physics and consider both cases:
On the client side, more FPS cannot do harm (no advantage for that player), but yields a bit better results (results are more exact the higher the FPS).
The Ca3DE server already runs at a fixed tick rate anyway. ;)

In summary, both a fixed and a varying physics framerate work, with barely noticable differences. As the server has final authority over game state, no matter what strategy it implements, the situation is fair for all players. As the server runs at a fixed FPS already anyway, I'd not worry about this issue. :)
Best regards,
Carsten
minosdis
Posts:24
Joined:2008-08-09, 05:42

Re: Physics, and how it applies to vehicles

Post by minosdis » 2008-08-27, 14:42

So I'm back from my vacation, and started working on the outline for the physics implementation this morning. One thing i'm wondering about is collision detection from stuff like bullets. Correct me if I'm wrong, but currently this is done with a ray test. I'm just wondering if this is what we want to do, or do we want to create an physics entity (still just a normal ent, except a method is called to add it to the physics world).
The reason I ask is because with PhysX, the character is controlled via the NxController class, which is seperate from the physics world. What this means is the character still needs to be added as a physics object, to avoid people running through each other. So if we're adding collision meshes for humans, why not add projectiles also.
PhysX does have raycasting also, with callbacks for all types of collisions (from rays, physics objects (actors)) including triggers. I guess the point of this reply is really just to raise the question, to what extent do we want to use the PhysX API? It seems to have these features that we could use:
* Character Controller
* Collision Detection for static and dynamic meshes (actors)
* Raycasting
* Triggers
* Vehicles
I think a lotof these features could be implemented fairly transparantly. For instance, triggers. The current trigger class could inherit from the public NxUserTriggerReport class, which has a method:
void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
then, define our trigger code here.
Basically, I think with some reworking of the game code, I think we could allow PhysX to do a lot of the leg work done currently by the ClipSys. That being said, is that necessary or even beneficial? It seems like the ClipSys works pretty well, and maybe if we just use PhysX for character control and eventually vehicles, that will be best. Not sure yet, and I'm running out of time at the moment for more ramblings :)

Also, off-topic, I haven't seen a changelog yet, or had a chance to test out the new RC's, are definable key bindings a new feature? ::nudge, nudge:: :)
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Physics, and how it applies to vehicles

Post by Carsten » 2008-08-27, 16:44

Dear MinosDis,
welcome back! :-D
minosdis wrote:So I'm back from my vacation, and started working on the outline for the physics implementation this morning. One thing i'm wondering about is collision detection from stuff like bullets. Correct me if I'm wrong, but currently this is done with a ray test. I'm just wondering if this is what we want to do, or do we want to create an physics entity (still just a normal ent, except a method is called to add it to the physics world).
Yes, right now bullets are computed with a ray-test, i.e. a non-stop straight-line test until the first hit.
There are also examples for (slower) projectiles that are implemented like true entities: The handgrenades and rockets are examples of that.
The reason I ask is because with PhysX, the character is controlled via the NxController class, which is seperate from the physics world. What this means is the character still needs to be added as a physics object, to avoid people running through each other. So if we're adding collision meshes for humans, why not add projectiles also.
I'd just mirror the existing approach: Use ray-tests with fast bullets, true entities with "slower" projectiles.
PhysX does have raycasting also, with callbacks for all types of collisions (from rays, physics objects (actors)) including triggers. I guess the point of this reply is really just to raise the question, to what extent do we want to use the PhysX API?
[...]
void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
then, define our trigger code here.
Basically, I think with some reworking of the game code, I think we could allow PhysX to do a lot of the leg work done currently by the ClipSys. That being said, is that necessary or even beneficial? It seems like the ClipSys works pretty well, and maybe if we just use PhysX for character control and eventually vehicles, that will be best. Not sure yet, and I'm running out of time at the moment for more ramblings :)
I think so, too: At least initially, I'd recommend to start with the smallest possible solution. For example, if we had a crate (or stack of crates) realistically move and fall, that would be a great start. This might not sound like much, but this "small" step would include all the basics of combining PhysX with Ca3DE.
Once that works, augmenting the system with more advanced physics objects in separate, subsequent steps is easier than if one wanted to implement all the features that PhysX provides at once.
Also, off-topic, I haven't seen a changelog yet, or had a chance to test out the new RC's, are definable key bindings a new feature? ::nudge, nudge:: :)
You're right, I'll add the changelog asap. I'll also try my best with the key bindings feature, but the focus on the upcoming release is clearly on CaWE usability improvements and bug fixes, which are very important in their own right, too. ;)
Best regards,
Carsten
minosdis
Posts:24
Joined:2008-08-09, 05:42

Re: Physics, and how it applies to vehicles

Post by minosdis » 2008-08-28, 16:33

Quick question, I'm trying to figure out how to get access to a number of things about the world. Here is what I need to know about the level:
num of Vertices
num of Triangles
Vertices (from PhysX documentation: Pointer to first vertex point. NOTE: vertices are of type NxVec3)
Triangles (Pointer to first triangle. Triangles seem to be of type NxU32)

So I guess PhysX needs an array of all the vertices and triangles in memory to 'cook' a mesh for the world. I can't seem to find this information publicly available in the game code, closest I could find is the private member, GameWorld->GetClipWorld()->WorldCollMdl

Once this mesh is cooked, it can either be kept in the memory or sent to a user stream and saved to the disk. I'm thinking the best way to do this would be when compiling a level, have CaWE cook the mesh and save it.. Ideas?

And in reply to your last post, I agree, a simple 'demo' would be best. Only problem is, a simple demo isn't necessarily simple. Say if we want to just add a few boxes, and let physx handle their collisions with each other. They still need to collide with the game world somehow, so we either need to a) also add the game world (see above) or b) let Ca3D handle this. If we go with b, then how do we tell Ca3D to handle collisions with the game world, but not other entities (the other boxes specifically). I think option a would be ideal, but we would first have to tackle the problem above, about where to find the vertice and mesh info for the entire game world.
minosdis
Posts:24
Joined:2008-08-09, 05:42

Re: Physics, and how it applies to vehicles

Post by minosdis » 2008-08-28, 17:40

:)
So I think I've figured out an easy way to create the mesh of the world for PhysX. Briefly looking over the cmap files created by CaWE it seems as though all the triangles (and vertices) are stored fairly cleanly there. I think I could write a standalone application run at compile time, similar to CaLight and CaBSP, that would read the cmap brush info, and serialize that into the correct format for PhysX. It would then cook the mesh and save it along side the world .cw . Then ingame, during the loading process, this mesh is loaded and added to the PhysX world as a static actor. I think this should work fairly well :)
Post Reply

Who is online

Users browsing this forum: No registered users and 24 guests