From: <ah...@un...> - 2009-12-03 08:55:59
|
Hi, As you can see on http://sourceforge.net/projects/simspark/ I'm diligently working on the APL right now. The bridge pattern seems to be the final solution to all the problems I had before. It's still an incredibly big task and very challenging at times, but I keep learning more and more about both simspark and C++ as I keep working, and I think I've reached the point where I finally enjoy working on the project and overcoming the challenges it proposes. However, I can't promise that I will actually get to implementing Bullet before the deadline. Since the design of the APL has taken so long and the project has proven to be far more complex than anybody expected, I changed my goal to at least get the APL done (i.e. unless avoiding this is completely impossible, no class that is not prefixed with "ODE..." includes the odewrapper anymore). That should already be a great help for anyone who wants to include Bullet, or PhysX, though. One thing that I stumbled across are the return types and method parameters. Since the abstract classes need to be engine-independent, I need to do something about methods like "dBodyID GetODEBody()" since dBodyID is defined inside of ODE. This is pretty easy, as I can just change it to something like "long GetBodyID()". A dBodyID _is_ a long, just with a different name, so the implementation can internally cast the dBodyID to a long before passing it on to the abstract layer. The class that called the method can then internally cast it back to a dBodyID and then work as usual. I think this is pretty clean, and it works flawlessly. This gets a little more tricky when you have pointers to ODE-specific types (which I think is only the case once, anyway). Since a pointer is just a memory address, the callee can cast to a void*, pass it on to the abstract layer, and the caller then casts it back to whatever type it expects and work with it. It still points to the same adress, so no harm is done. However, I have not found a clean solution for references yet, and references are used quite often. The solution would be to change it to a neutral type, use that neutral type in the abstract layer and then change it back to what is needed, and I can say that this works. I tested it with a method that got a dMatrix3& as a parameter (i.e. I changed it to a neutral type and internally changed it back to a dMatrix3&), and I know exactly what would have happened if this method had malfunctioned. However, C++ forbids a void&. So I cast to an int&. Let me emphasize. The Collider class, at one points, needs to call PhysicsObject::ConvertRotationMatrix. CRM expects a dMatrix3& as a parameter. This has to be avoided because PhysicsObject needs to be engine-independent and a dMatrix3 is an ODE type. So, I let Collider cast to an the dMatrix3& to an int&, call CRM with that reference, PhysicsObject delegates it to ODEPhysicsObject, and ODEPO casts the int& back to a dMatrix3&. This works. I realise, however, that this is nothing more than a dirty workaround. Do you know a better way to encapsulate a reference in an independent type and then retrieve the encapsulated reference? If not, is this workaround acceptable at all, or does it discredit all of my other work? :D thanks, Andreas |