From: Hedayat V. <hed...@ai...> - 2009-12-07 19:23:23
|
Hi, On ۰۹/۱۲/۰۳ 12:25, ah...@un... wrote: > Hi, > > > As you can see onhttp://sourceforge.net/projects/simspark/ I'm diligently > working on the APL right now. Yes, great! Thanks. > 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. > Nice to hear that :) > 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. > Yes, certainly. > 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. > Yes, as long as the types used by different engines are compatible it is fine. > 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. > Yes. I suggest to define an appropriate typedefs for different engine specific types so that you use something more meaningful than void* (e.g. typedef void *GenericColliderPtr). > 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 > There are different solutions for this problem. One of them is like this: define a PhysicsMatrix class. Then for each engine, derive a class from PhysicsMatrix class. For example, we could have a ODEMatrix class derived from PhysicsMatrix class. Now, this class could either have a member of type dMatrix3 inside it, or being derived from dMatrix3 too (it is even possible to put a dMatrix3& member inside the class which is initialized in the constructor). Boost library also provides many classes which might be helpful in these situations, but I'm not sure if they are really convenient here. Keep up the good work, Thanks Hedayat > > thanks, > > Andreas > > |