Thanks a lot for this updated version. Much appreciated.
Nice to see the moveGlobal* methods supported now - I’ve been meaning to ask you about them, but those performance troubles in my application throw everything else into disarray… Also, pstats collectors are awesome! Thanks again.
Unfortunately, there is no speedup - at least in my particular case. In fact, it’s actually slightly slower than iterating over joints in Python and calling setGlobalMat() methods on corresponding PhysActor objects.
Just to see if it was going to make any difference, I’ve experimented a bit with your latest source: in particular, tried using setGlobalPose() instead of moveGlobalPose() in PhysActor::update_inverse() method. Interestingly, while the moveGlobal* methods themselves are slightly faster than setGlobal* ones, they seem to put additional computational burden on doPhysics. Which makes sense somewhat, if we take this quote from PhysX SDK documentation as a hint: “Instead, it becomes mobile when the user sets a slightly different position with the moveGlobal*() functions. NOTE: Do not use the setGlobal*() functions to make the actor mobile; it will disable many of the advantages that kinematic objects provide, such as having the appearance of infinite mass and the ability to push regular dynamic actors out of the way.”
here are pstats from my experiment, if you’re curious (all milliseconds):
Sadly, either way it’s not fast enough for the sort of frame-rate that i’m aiming for. Of course, that’s by no means the fault of PandaPhysX or PhysX or Panda3D engine. It’s the way i’m using these systems that is suspect. Perhaps, i need to re-think the whole setup of joints/actors. (Maybe there needs to be some sort of clever hierarchy to aid in collision detection optimizations, or maybe these actors shouldn’t be kinematic after all…)
I have expected moveGlobalMat() to be slower than setGlobalMat(), but still I would opt for moveGlobalMat(). The reason being that this way you could push the ball around, and not just make it bounce of randomly (assuming you are trying to build a soccer game, because of 22 = 2 * 11 players).
Building hierarchies of nodes probably makes it worse, since PhysX only knows the global transform, and lots of time could be spend on calculating the global transform of each NodePath.
I would try and search physics forums for how others have solved similar problems with sports games. This is what I have found on an ODE forum:
Maybe it would be a good idea to leave all 22 players simple shapes. This should be enough for player/player collision. And fake kicking the ball: just apply an impulse to it when the player kicks it.
Yep, it is a soccer game. And yes, fortunately/unfortunately, i am all too familiar with the shortcommings of both FIFA and PES/WE (Konami) series’ of games.
Believable ball physics is one of the main goals of my project. So it really needs to “feel” right Otherwise, there’s no point really… I will definitely experiment with simpler collision approximations for the players. Box-per-joint was sort of the obvious first thing to try… Doing one actor-per-player is an option, and may end up being the only choice at the end, but it’ll probably need a lot of black magic to get it to look well.
I’ve been thinking again about your suggestion about using simple shapes for the players, and realized that i can actually have 2 collision geometries per player: one simple box - used most of the time, and another - a more detailed approximation with a box/physActor per joint. The second one is only switched to when the ball is close enough to a player, and there’s a chance of collision. Tried a quick experiment, and this seems to work quite well - i’m getting a lot more fps!
I have been thinking about this too. Switching to a detailed mode only when the ball is close is certainly a good way to improve performance.
Maybe you can reduce the amount of shapes even more. In soccer there are only three interaction with the ball: (1) kicking it with the foot. Most players have one “strong” foot, so there needs to be only one foot. (2) head, (3) stopping the ball with the chest. So maybe three solids are enough.
I don’t want to discourage you, but I consider your goal very ambitious. This forum is full of post matching this patter: “I (and maybe one or two friends) want to create a game which has better than what sells.” Now, those big game companies have dozens if not hundred man-years of knowlege/experience with their specific genere. Knowledge they don’t share with open-source developers. I think a realistic goal would be to get close to what known games already offer in terms of realism/visual quality/size and details of the environment.
About soccer: the player wants to shoot the ball to a desired target point. To do so (using his foot) he has to decide if he plays it with the inner foot, outer foot, or in some cases the tip. Then the has to rotate and tilt the foot, and he has to choose the right speed vector to give the ball the right spin. This is just a very simple analysis, and reality is way more complex. A soccer player doesn’t set these “parameters” intentionally. His cerebellum does the trick, knee-jerk, pulling the right “parameters” from his expeirence.
I doubt that a simple box for the player’s foot will be enough to provide a realistic model. Without having ever worked on a sports game I would suggest to develop simple algorithms for e.g. (1) shooting the ball somewhere, (2) stopping the ball, (3) dribbling with the ball, and so on.
For example the algorithm for kicking the ball somewhere could accept the desired target point and maybe the desired speed as parameters, compute a force that will set the ball on a trajectory to the desired target, play a proper anomation, and that’s it. No collision shapes for the leg involved. To fake the players soccer skill an arbitrary error could be added.
but again, I am neither a soccer expert not do I know how sports games work inside.
You make valid points, and your suggestions and advice are much appreciated. It’s an ambitious project, i’m under no illusion about that. But that’s part of the fun. There is no schedule, and i’m in no particular rush to get it done as soon as possible, so i’ll take my time and work out the issues as they come.
This isn’t a crusade against Konami, EA, or any other commercial vendor. The goal is to offer a somewhat different point of view on a soccer game. Not so much of shiny graphics and accurate player faces, but believable physics and open AI system.
I was playing around with the vehicle sample and found that you do not create a PhysWheelShapeDesc on which you can set a unique material for the wheel. Now the problem is that I can not see where to use a PhysWheelShapeDesc. I can’t find any function of PhysWheelDesc or PhysVehicleDesc that takes a PhysWheelShapeDesc as a parameter. How can I set a wheels material? Did I miss something?
I may have missed it (didn’t read the entire thread) but what is the license for this? Seems like the SDK is pretty restrictive, not sure how this relates to panda3d.
Vehicle, VehicleMotor, VehicleGears & Wheel are convenience class USING other PhysX objects. They are NOT PhysX objects itself. High-level helpers if you like. The idea for these classes comes from the samples from the NVIDIA PhysX SDK. Unfortunately they don’t work well. I consider them experimental features. I suggest using ODE for easy creating of vehicles.
If you want to use PhysXthen you can go two ways: either use PhysWheelShape/PhysWheelShapeDesc directly, and create you own vehicles in Python, or modify the C++ code of PhysVehicle etc. to fit your needs.
Sample 17 shows how to use PhysWheelShapeDesc/PhysWheelShape directly. You will notice that you have to do a lot of work yourself if starting that low-level, e. g. wheel blocking when moving around corners because the two front wheels are set to the same steering angle.
Have a look at the readme file and the license file which come with the download.
This (thread) is open source software which builds on top of two large libraries: (1) Panda3D, and (2) NVIDIA PhysX. My own code being release as open source does not imply that Panda3D or NVIDIA PhysX have to be open source. You have to accept three licenses at the same time if using code from this thread:
my own license (which is zlib style),
Panda3D license
and NVIDIA PhysX SDK license
Be sure to read all three carefully, especially the PhysX SDK license. It is restrictive!
I got the vehicle sample to work ok… I think the biggest reason why it won’t work well is because you can’t set a wheel’s traction.
I found the following in the physWheelDesc.h file:
Why is this ‘Old Style’, and not implemented anymore?
I also would like to be able to change the MaxTurnAngle on the wheels every frame to a value dependent on the velocity of the vehicle, which I can easily do in the wheels sample.
Another problem is that when 2 cars collide they fly into the air, but I think that this is probably also due to the fact that I can’t set a wheels’ traction/friction.
Should I just give up on using PhysVehicle or could it be possible to find some kind of workaround or implementation of the above?
Because I did only implement those parts of the PhysX samples which use new style raycast wheels (aka NxWheelShape, wrapped by PhysWheelShape). The old style, friction and collision shape based wheels have not been implemented.
Makes sense to reduce the maximum possible steer angle with increasing speed. You don’t want to set a steer angle of 30 degree at 100kmh. Just add getters/setters to PhysVehicle. I will do so for the next release too.
Maybe. But since wheel shapes don’t use “simple” friction skalars the above mentioned methods won’t help. What needs to be done is to offer NxTireFunctionDesc on the Python layer (assuming tire friction is the reason for you flying cars).
sigh Hard to say without knowing your goals and abilities. I consider vehicles a highly experimental area. You will have to work on the C++ layer, for sure, so if you are not willing/able to compile then you should probably use another physics engine for vehicles. Panda wrappers for PhysX are not yet complete enough to fully support vehicle physice. ODE has very good and easy to use vehicles classes, for example. I don’t have time these weeks to work on vehicles, sorry.
Assuming I have some C++ experience, how much work is it to use PhysX directly with Panda, without the wrapper? Are there any tutorials on this, or should I just look at the SDK docs? I have to start using C++ instead of Python anyway.
If you are familiar with the PhysX wrappers then you won’t have much difficulties using PhysX directly from C++. There are no tutorials for Panda3D + PhysX on C++ layer, but you always can look at the PhysX SDK samples and at my code (for how to synchronize the scene graph for example).
The PhysX SDK/integration into Panda3D is what I’m most curious about. I tried to read through the PhysX EULA, but I’m not sure I understand it all.
Let me ask it this way, if someone to make a commercial/shareware game using Panda3D, including just the opensource/free to use stuff like OpenAL, could they use the PhysX stuff as well?
I’m not planning anything like that myself, but you never know.
Welcome to the club. I don’t think I understand it well too.
I think it is possible, if they do everything the NVIDIA PhysX license requires (and Panda3D etc.). Sorry, there is no way around this. You can’t use the Panda3D integration if you don’t stick to the NVIDIA license.
I’ve decided to try and use the wrapper with C++ and convert my current Python vehicle test to C++. I got the basic example, posted earlier, to compile and run properly. But after trying to create a PhysVehicle I’ve run into some problems.
Firstly, the PhysVehicleDesc’s add_shape(), add_wheel(), set_motor() and set_gears() functions all need pointers to the descriptor of each. So I created pointers for each and now I’m getting a list of errors starting with the following:
I think it is better style to create values for each and pass them by reference, using the address operator.
This just means that the linker can’t find the object code for motor desc and gears desc. Seems like you either forgot to compile these files, or if you did compile them you forgot to link against them.
I don’t get it, I am linking the wrapper, libpandaphysx.lib. I compiled the wrapper and tested the vehicle through python(*) with the newly compiled wrapper, which works. Even the basic c++ example compiles. Am I just missing something?
Ok, then these symbols get not exported by the lib. My fault. Please edit the header files for PhysVehicleMotorDesc, PhysVehicleGearsDesc and PhysRay like this: