From: <ah...@un...> - 2009-11-10 09:04:24
|
Hello, After taking a long and careful look at the source code and thinking about the greater picture, here are my conclusions. I'd like to (1) keep the current dependency tree for the abstract physics layer and (2) go crazy on the multiple inheritances. (1) - The current design is very well thought out and, more importantly, many other parts of simspark expect it. Any major changes in the dependency tree require adjustments in many other parts of the system, mainly the parsers and other plugins that work with oxygen. Also, with an abstract physics layer that stays true to the current design, it should be easy to integrate the current ODE-specific code into it. Any changes to the design require large parts of the current code to be rewritten - I can tell this from first-hand experience because I've been trying to apply the new design for about one and a half weeks before I decided to rethink it, and I still had many unsolved problems despite only focusing on basic functionality. (2) - I think it's pretty easy to argue that multiple inheritances are needed. As far as I know, there are only two ways for an object to call a non-static method: To implement it itself, or inherit from a class that implemented it. So, let's look only at PhysicsObject for now. It's a simple class providing some functionality that is the same for every physics object: finding out which space or world an object is in, or converting its rotation Matrix to something that Salt can work with. All these methods use ODE-specific code, so either every ODE-specific subclass implements it itself, or an ODE-specific superclass is implement that only ODE-objects, but not Bullet-Objects inherit from. The first possibility would generate more than three thousand lines of redundant code - and that's only talking about the ODE-specific part of the code equal for all physics objects. Also, multiple inheritances wouldn't be that convulted. The simple rule would be that every engine-specific class would have to inherit from its parent class, and all engine-specific subclasses of superclasses of its parent class. Sounds confusing, but it's quite easy: E.g. ODEBoxCollider would inherit from BoxCollider (parent class), and since Collider and PhysicsObject are superclasses of BoxCollider, it would also inherit from ODECollider and ODEObject. I will discuss this design with Joschka tomorrow, but you're welcome to tell us what you think, as well. thanks, Andreas |
From: <ah...@un...> - 2009-11-12 12:36:08
|
Hello, After working with multiple inheritances for a day and a half, I ran into new problems. Diamond Inheritances cause ambiguity problems due to Zeitgeist's design, and after cutting some inheritances, it led to the problem that some classes weren't derived from BaseNode anymore, and thus lost the functionality of a SceneGraph Node that they need to have in order to work. The ambiguity can be resolved with virtual inheritances, but then you get trouble with boost's static casts if they find virtual base classes down the line. Anyway, we had to come up with a new design that fulfilled three requirements: 1) All classes that I want to create objects of must be derived from a common base class, e.g. ODESphereCollider and BulletSphereCollider from SphereCollider. Necessary because calls like SphereCollider* soccerball = new ODESphereCollider() must work. 2) All classes that I want to create objects of, and the classes that these classes are derived from, must be derived from BaseNode. Necessary because the above mentioned ODESphereCollider must be added to the SceneGraph, and many, many external classes expect classes like Body, Collider or BallJoint to be derived from BaseNode. 3) When inheriting from multiple classes, the parent classes must not have a common Base Class. Necessary because of the ambiguity problems described above. Some people were against sticking to the old design. Even if I use the new design, I can still limit myself to the old functionality for the time being and add all the new stuff (like SoftBodies) as empty placeholder classes for the time being. When they're there, somebody can implement them later. We also looked at PAL. PAL uses virtual inheritances a lot to solve the ambiguity problems. (Actually, PAL was what made us know that virtual inheritances exist). All this led to the rather unorthodox design you can see here: http://www.uni-koblenz.de/~aheld/APL%20Design%20Sample.png Note that this omits a great number of classes for the sake of readability. The uncontinuous arrows denote that the child class will only inherit from one of these. E.g. when ODE is used, Body gets derived from ODEBody, else from BulletBody. The preprocessor will decide on that. The tasks of the non-engine-specific classes, like Body and BoxCollider, is to pick the correct base class, make sure that the leaf classes can inherit the proper engine-specific code, and provide the SceneGraph-related functionality that many external classes expect. I hope that I finally found a design that will work, since I'm feeling rather burned out. There are six DIN A4-sheets on my desk that all have UML diagrams on them, as well a few xmi files on my computer :P Like always, any objections/remarks are welcome. thanks, Andreas |
From: Hedayat V. <hed...@ai...> - 2009-11-12 15:31:46
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html style="direction: ltr;"> <head> <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"> </head> <body bgcolor="#ffffff" text="#000000"> Hi again :)<br> <br> On ۰۹/۱۱/۱۲ 04:05, <a class="moz-txt-link-abbreviated" href="mailto:ah...@un...">ah...@un...</a> wrote: <blockquote cite="mid:c35...@ma..." type="cite"> <pre wrap="">Hello, After working with multiple inheritances for a day and a half, I ran into new problems. Diamond Inheritances cause ambiguity problems due to Zeitgeist's design, and after cutting some inheritances, it led to the problem that some classes weren't derived from BaseNode anymore, and thus lost the functionality of a SceneGraph Node that they need to have in order to work. The ambiguity can be resolved with virtual inheritances, but then you get trouble with boost's static casts if they find virtual base classes down the line. Anyway, we had to come up with a new design that fulfilled three requirements: </pre> </blockquote> Sorry, would you please present an example of required diamond inheritance? I wonder why abstract physics classes should be derived from BaseNode.<br> <br> <br> Thanks,<br> Hedayat<br> <br> <blockquote cite="mid:c35...@ma..." type="cite"> <pre wrap=""> 1) All classes that I want to create objects of must be derived from a common base class, e.g. ODESphereCollider and BulletSphereCollider from SphereCollider. Necessary because calls like SphereCollider* soccerball = new ODESphereCollider() must work. 2) All classes that I want to create objects of, and the classes that these classes are derived from, must be derived from BaseNode. Necessary because the above mentioned ODESphereCollider must be added to the SceneGraph, and many, many external classes expect classes like Body, Collider or BallJoint to be derived from BaseNode. 3) When inheriting from multiple classes, the parent classes must not have a common Base Class. Necessary because of the ambiguity problems described above. Some people were against sticking to the old design. Even if I use the new design, I can still limit myself to the old functionality for the time being and add all the new stuff (like SoftBodies) as empty placeholder classes for the time being. When they're there, somebody can implement them later. We also looked at PAL. PAL uses virtual inheritances a lot to solve the ambiguity problems. (Actually, PAL was what made us know that virtual inheritances exist). All this led to the rather unorthodox design you can see here: <a class="moz-txt-link-freetext" href="http://www.uni-koblenz.de/~aheld/APL%20Design%20Sample.png">http://www.uni-koblenz.de/~aheld/APL%20Design%20Sample.png</a> Note that this omits a great number of classes for the sake of readability. The uncontinuous arrows denote that the child class will only inherit from one of these. E.g. when ODE is used, Body gets derived from ODEBody, else from BulletBody. The preprocessor will decide on that. The tasks of the non-engine-specific classes, like Body and BoxCollider, is to pick the correct base class, make sure that the leaf classes can inherit the proper engine-specific code, and provide the SceneGraph-related functionality that many external classes expect. I hope that I finally found a design that will work, since I'm feeling rather burned out. There are six DIN A4-sheets on my desk that all have UML diagrams on them, as well a few xmi files on my computer :P Like always, any objections/remarks are welcome. thanks, Andreas </pre> </blockquote> </body> </html> |
From: <ah...@un...> - 2009-11-13 03:20:28
|
Hi, > Sorry, would you please present an example of required diamond > inheritance? class Top {}; class Fork : public Top {}; class LeftBranch : public Fork {}; class RightBranch : public Fork {}; class Bottom : public LeftBranch, public RightBranch {}; In this case, Bottom is derived from Fork twice, once via LeftBranch and once via RightBranch. This works in C++. However, when you write: Top* instance = new Bottom(); You get a compiler error because Top is an ambigious base class of Bottom. Simspark wants to do something like zeitgeist::Object* = new Body(); and you get the same error at this point. You should be able to reproduce it by deriving BoxCollider from both Collider and ODEObject in the current version. It's nonsense, but it leads to ODEObject and everything above it being ambigious base classes of BoxCollider. > I wonder why abstract physics classes should be derived > from BaseNode. In order to add an instance of a class to the scenegraph, it has to be derived from BaseNode. That's written in the documentation at some point. This doesn't mean that the abstract classes have to be derived from there, though. I tried an approach that derives the non-abstract classes from BaseNode in a seperate tree and keeps the abstract classes as interfaces and pointer-providers that aren't derived from anything. This, however, gets very ugly because patterns like boost::shared_ptr<Body> body = [...]; [...] body->GetSelf() [...] can be found in many places outside of oxygen. GetSelf is specified in zeitgeist, so if the inheritance from Body to BaseNode is cut, GetSelf isn't known to Body anymore. Figuring out a design that derives Body from BaseNode is by far the easiest solution to that problem. I hope this answers your questions. |
From: Ing. M. B. <mar...@gm...> - 2009-11-13 17:36:48
|
Hi Andreas. I'm not guru in Simspark like you or Hedayat :) . But if you have a problem with multiple inheritance, try this >>> class Top {}; class Fork : public Top {}; class LeftBranch : virtual public Fork {}; //word virtual class RightBranch : virtual public Fork {}; //word virtual class Bottom : public LeftBranch, public RightBranch {}; Now, if you create instance of class Bottom >>> Top* instance = new Bottom; compiler get no error. Best Regards Marian -----Original Message----- From: ah...@un... [mailto:ah...@un...] Sent: Friday, November 13, 2009 4:20 AM To: sim...@li... Subject: Re: [simspark-devel] APL Design Hi, > Sorry, would you please present an example of required diamond > inheritance? class Top {}; class Fork : public Top {}; class LeftBranch : public Fork {}; class RightBranch : public Fork {}; class Bottom : public LeftBranch, public RightBranch {}; In this case, Bottom is derived from Fork twice, once via LeftBranch and once via RightBranch. This works in C++. However, when you write: Top* instance = new Bottom(); You get a compiler error because Top is an ambigious base class of Bottom. Simspark wants to do something like zeitgeist::Object* = new Body(); and you get the same error at this point. You should be able to reproduce it by deriving BoxCollider from both Collider and ODEObject in the current version. It's nonsense, but it leads to ODEObject and everything above it being ambigious base classes of BoxCollider. > I wonder why abstract physics classes should be derived > from BaseNode. In order to add an instance of a class to the scenegraph, it has to be derived from BaseNode. That's written in the documentation at some point. This doesn't mean that the abstract classes have to be derived from there, though. I tried an approach that derives the non-abstract classes from BaseNode in a seperate tree and keeps the abstract classes as interfaces and pointer-providers that aren't derived from anything. This, however, gets very ugly because patterns like boost::shared_ptr<Body> body = [...]; [...] body->GetSelf() [...] can be found in many places outside of oxygen. GetSelf is specified in zeitgeist, so if the inheritance from Body to BaseNode is cut, GetSelf isn't known to Body anymore. Figuring out a design that derives Body from BaseNode is by far the easiest solution to that problem. I hope this answers your questions. ---------------------------------------------------------------------------- -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Simspark Generic Physical MAS Simulator simspark-devel mailing list sim...@li... https://lists.sourceforge.net/lists/listinfo/simspark-devel __________ Information from ESET NOD32 Antivirus, version of virus signature database 4593 (20091110) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com __________ Information from ESET NOD32 Antivirus, version of virus signature database 4593 (20091110) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com |