
"Janek Kozicki" wrote
Andy Little said: (by the date of Tue, 21 Mar 2006 02:00:43 -0000)
sorry that this post got so incredibly long ;)
No problem. I will try to reply to the other parts of your post in more detail soon. Overall I can see a good deal of divergence between your aims and mine. (That is not necessarily a bad thing of course as we would presumably be aiming for the most widespread use). Your applications require very good raw speed performance, which I havent paid enough attention to, but I can see now why you will be obsessed with that from looking at YADE.
I've reconsidered my "raw-speed" attitude, because from experience I've learnt that speed comes often uninvited along with good design. So think about design first, speed comes later :)
My elaborate explanations about anonymous union simply demonstrate that full opengl compatibility comes at huge price - it forces internal data structure. A huge no-no in good OO design. Therefore degree of compatibility with opengl should be a design decision/rationale of this library.
Yes. I havent actually used OpenGL, but my understanding is that it is very low level and it is possible to apply some higher level OOP above the level of the low-level OpenGL functions, while keeping in mind the performance issue. The C++ facilities such as inlining and namespaces and templates can be used to good effect to simplify the use of the OpenGL API functions as well of course without (theoretically) loss in performance. For example the OpenGL shading language specification lists various types in section 4.1 of the shading language manual e.g (among others) vec2 a two component floating-point vector vec3 a three component floating-point vector vec4 a four component floating-point vector bvec2 a two component Boolean vector bvec3 a three component Boolean vector bvec4 a four component Boolean vector ivec2 a two component integer vector ivec3 a three component integer vector ivec4 a four component integer vector With C++ templates one could represent all those in one class template namespace gl_wrap{ template<typename T, int Dimension,> struct vec; } Secondly, the OpenGL?vec? family above is used IIRC as a standard container for different purposes, such as a vertex, or a color, but IMO it would be more 'user friendly' to create a color type and a vertex type and only convert them to their low level OpenGL ?vec? equivalents for output, namespace gl_wrap{ template <typename ValueType> rgb_color : gl_wrap::vec<3,Value_type> {/*...*/}; template <typename ValueType> vertex3 : gl_wrap::vec<3,Value_type> {/*...*/}; } Note: those two are only very naive examples and certainly not intended to be representative of a particular design but rather indicating that the OpenGL API doesnt need to be followed religiously, but ideally without losing performance of course, which can only be discovered by testing I guess. The general thrust of the above is that I would prefer to end up with a User Orientated design as opposed to a design which provides low level primitives of indeterminate meaning (eg using the same vector type to hold a vertex and a color as raw Open GL does). The downside of using higher level Concepts is that One may end up with a lot of structurally similar looking entities. The upside may be that what we are really discussing is Concepts which might correspond with the SoCalled Generic Programming approach. A simple example of the difference. Say we have some output function. Using the "structurally everythings equivalent approach so lets just use a vect3" we might use a vect3 for volor and vertices: set Mode(RGB_COLOR) ( eg vector following is meant to be a Color) out << vect3(R,G,B); setMode(VERTEX3); ( eg vector following is meant to be a Vertex) out << vect3(x,y,z); OTOH In the Concept approach vertices and colors are separate types : out << rgb_color(r,g,b) << vertex3(x,y,z); // Fact that compiler can //distinguish these two types is very powerful NB The above is probably Incredibly Obvious but I thought I'd say it anyway as designing around Concepts is very much not a feature of raw OpenGL that I can see.
Fast disply in yade is much less important than geometrical computations themselves - related to physics of the system, not to the graphics.
Overall I have been looking at ease of use. I am currently interested in integrating geometry /vectors with pqs library, but that would increase complexity of the implementation over just using float types as you may see in my current geometry offering and will also affect compile times, so may be a burden giving you no benefit.
I see a big potential here, if I want to use physical units, having them built-in inside the geometry would be pretty useful.
OK. I guess that rather than geometry what we are discussing may actually be a library for modelling physical processes in (usually 3d but possibly 2d) space , and time? I dont think theres a problem with that ... except to note that geometry is a math subset of the wider physical problem and the geometry principles do apply there.
That difference of quaternions v matrices is interesting also. The generic nature of matrix transforms is at the expense of speed. It should be possible to combine both matrix and quaternions transforms somehow of course and I will have to read up on using quaternion.
In fact quaternion stores rotation data in more compact form than matrix.
Ok. I have heard of that, but dont know the details.
If quaternion is 'messed up' a bit, then rotation angle is just a bit different - hard to notice the difference. If matrix is 'messed up' a bit - it losts symmetry and rotation is iffy. Moreover everytime a vector3d is rotated by quaternion, a 3x3 matrix is built from quaternion (using only operations + - *). And to be honest I haven't benchamrked if quaterions are faster. Many people claim this, but I realized that I shouldn't claim it until I'll make relevant benchmarks.
I think the clue to speed is that quaternion uses a 3x3 matrix whereas a transform matrix to do same job would be 4x4 (which is a lot more calcs many redundant!), though 4x4 matrix can hold information about perspective and translation which a quaternion cant AFAIK. Also 1 matrix can hold an arbitarily complex transform by concatenating (multiplying) a series of matrices of simpler transforms. e.g any sequence of rotations, translations, scalings, perspective transformations, mirror etc. I take the point about the cleaner math involved in quaternions too though I have to confess that I will have to work to understand the quaternion math. Again it might be helpfull to talk about the general Concepts that a transform entity offers, such as it can rotate , it can scale, it can translate etc or not. It may even be possible to choose a particular coordinate transformer at compile time by selecting the minimal /most efficient one that fulfills the given input parameters. Keeping it simple of course ! NB You seem to be using quaternion to model a physical state, rather than as a transform so I may have that wrong.
It strikes me that perhaps more detailed discussion about the goals and rationale of such a library is needed too.
yes, certainly. At first we should decide what entities should appear, how to name them, and how to sort them into namespaces, to begin with, that's my library:
- vector2 + - vector3 + - vector4 + - matrix2 + - matrix3 + - matrix4 + - quaternion + - se3 +
OK. That seems like a good initial set. It would probably clarify to provide some more description. eg purpose of and some useful operations on each entity. In the library sketched out in the Math -Geometry director in the Vault, my idea was to group by whether a particular entitity makes sense only in a 2D or 3D space (Which requires the emphasis on higher level Conceptual rather than lower level general purpose entities, and two_d/ three_d namespaces) .I tried to create primitives with more specific meanings or useage and put them in 2D/3D namespaces: e.g ( adding some other entities) 2D namespace{ // " a point in 2d space" vertex {x,y} // " a direction in 2d space" vector {x,y} // NB the issues of addition of vertices (or points) meant that a vector may serve for both in practise. (OTOH just allow addition of vertices) // " a 2d vertex normalised for multiplication by a homogeneous matrix" homogeneous_vertex {x,y,h} // not sure what this would be used for though but it would be / equivalent to the 3x3 matrix in the 3D namespace //(maybe used by complex as 3D one is by quaternion? matrix // 2 x 2 // Transform matrix. concatenate and multiply by homogeneous vector homogeneous_matrix //(3 x 3 ) // fits here because its 2d version of quaternion AFAIK.? std::complex // also some sort of physical entity with position and direction I think similar to the "se3" // I have called it l it a field element ? field_element { vertex, vector} //OR field_element (vertex, complex} } // ~ 2D namespace 3D namespace{ // " a point in 3D spac" vertex // {x,y,z} // for representing 3d vector quantities force etc // " a direction in 3d space" vector // for holding 3d homogeneous coordinates // convertible to from ordinary vertex // Used for compatibility with 3d transform matrix homogeneous_vertex // {x,y,z,w} // 3 x 3 matrix Used by quaternion? // but note a different 3x3 matrix in both 2D and //3D namespace matrix // 4 x 4 transform matrix homogeneous_matrix // for representing a direction? Naturally I think this makes sense in a 3D space only? quaternion // physical entity with position and direction similar to the "se3" // I have called it l it a field element ? field_element { vertex, vector} //OR field_element (vertex, quaternion} } // ~ 3D namespace Not everything fits in 2D/ 3D of course e.g colours have nothing to do with do with 2D or 3D (Maybe they dont in a geometry library either!)... but no problem ...give them their own grouping namespace colours{ rgb {r,g,b} rgba {r,g,b,a} }
Other readers of this list are welcome to add more components and "vote" by placing '+' next to it. Of course class names are subject to another discussion :)
If you are wondering, se3 is a position/orientation combo - small class which contains only vector3 and a quaternion. It is used to fully describe a placement of an object in 3d space. I'm still not sure whether getting rid of it would make things simpler or not.
Right I have in mind a similarish entity but I used a position- vector (vector3) for the position and another using the relevant quantity ( flux_density/ circulation etc) for the direction/magnitude ( <--- quaternion fits there? ). Called it 'field_element' I think. I guess its also a basis for attaching spheres and boxes etc?
As to quanternion...is boost::quanternion not suitable for your applications as it stands?
unfortunately not. yesterday I have examined it again, and I see that the author has started working in that direction (quote at bottom of quaternion docs webpage: "Use uBlas for the link with rotations (and move from the example implementation to an efficient one).").
In his example I can see those familiar formulas used to build rotation matrix out of quaternion (in file HSO3.hpp)
Perhaps he got discouraged by the fact that ublas is not a good choice for small vectors.
Unfortunately the documentation . http://www.boost.org/libs/math/quaternion/TQE.pdf iss way out of my depth:-( Hopefully theres a more earthy definition of quaternions somewhere ! Apologies that the above is somewhat sketchy and hope it makes some sort of sense. regards Andy Little.