Hello Carlo,
Carlo Orru wrote:
For a general solution it is probably acceptable to go through the string accessors, it would be nice if it was possible to allow the user to replace this with something that requires knowledge of the type of the field being changed but can use e.g. the vector interface to modify values.Could you please explain it better? How could such thing be accomplished ?
sorry, rereading this I realize now that it is rather hard to understand without knowing what I was thinking at that time ;) The functions that return/take strings to modify the field content basically provide a very generic interface to fields, as you can use them with minimal static type information (i.e. you only need a Field * and the virtual functions Do The Right Thing). However, if it is known that the Field * actually is a MFUInt32 * one can call a specialized function for that case or instantiate a template and inside use operator[] to modify the field contents, without having to go through the virtual string interface. So for the general (or fallback) case the string interface can be used, but when the user is willing to provide more information (i.e. the type of the field at compile time), a more efficient accessors could be used.
ok. What is the reason for FieldWrapper<T>::Interpolate taking two FieldWrapper<T> arguments and not two T arguments ?Well, actually, there is no reason... Thanks for pointing it out...Also, in what sense IS FieldWrapper<Quaternion> A Quaternion, i.e. why does it publicly derive from it?Because in the beginning I wanted every field to be able to update itself via the "Interpolate" method, i.e. I wanted to do something like this: TransformPtr tr = Transform::create(); FieldWrapper<Quaternion> fw_q(Quaternion(Vec3f(1,0,0), deg2rad(60))); tr->setRotation(fw_q);
this is basically a case of slicing; the field only stores a Quaternion so everything else is sliced off fw_q and tr->getRotation only gives you a Quaternion back.
In this way I thought I'd be able to directly update the field just by calling FieldWrapper<Quaternion>::Interpolate. Well, I was wrong.I'm trying to understand why this is necessary or a good thing to do; so what could something like the following not do?// base template template <class FieldT> struct FieldValueInterpolator; // partial specialization for SF template <class ValueTypeT, Int32 NamespaceI> struct FieldValueInterpolator<SField<ValueTypeT, NamespaceI> > { typedef SField<ValueTypeT, NamespaceI> SFieldType; typedef typename SFieldType::ArgumentType ArgumentType; void updateField(Real32 fract, ArgumentType val0, ArgumentType val1, FieldContainerPtr pCont, UInt32 fieldId) { SFieldType *pCastSF = static_cast<SFieldType *>( pCont->getField(fieldId)); // interpolate between val0 and val1 depending on fract, // which is in [0,1] // write value to pCastSF using pCastSF->setValue() } }; // partial specialization for MF template <class ValueTypeT, Int32 NamespaceI> struct FieldValueInterpolator<MField<ValueTypeT, NamespaceI> > { typedef MField<ValueTypeT, NamespaceI> MFieldType; typedef typename MFieldType::ArgumentType ArgumentType; void updateField(Real32 fract, ArgumentType val0, ArgumentType val1, FieldContainerPtr pCont, UInt32 fieldId) { MFieldType *pCastMF = static_cast<MFieldType *>( pCont->getField(fieldId)); // interpolate between val0 and val1 depending on fract, // which is in [0,1] // write value to pCastMF using pCastMF->push_back(), // (*pCastMF)[i] etc. } };Admittedly, I have not fully thought through this idea and I'm not convinced that all the static typing is necessary/helpful at this level, but something similar might be used at a very low level to avoid the string accessors (sorry, for being pedantic about this, I don't like string based interfaces much ;) ).This seems to be a very good way to interpolate the two values, but: - How do I get the "fieldId" parameter ?
there are two ways, one to get it at compile time and one to get it at
runtime.
Node::ChildrenFieldId gives you the id of the children field of Node at
compile time, while
NodePtr n;
n->getType().getFieldDescription("children")->getId() gives you the same
thing at runtime.
- Is there any way to know what kind of value we are dealing with other than looking at the name string ? (I need to know the type in order to be able to perform the interpolation!)
that is a fundamental challenge when writing (object oriented) software and in general C++ offers two solutions: - by designing a class hierarchy with a common interface, you do not need to know the (exact) type anymore, as the virtual function call mechanism determines the right function to call, depending on the actual type of object you are dealing with. This approach becomes problematic when you need to pass values of different types to a function that essentially performs the same task for these types (i.e. interpolation between two values), because it is not clear what the necessary common interface should be. - templates allow you to preserve the static type of objects, without manually writing code for every possible type. Templates have their own problems of course, as excessive use is known to cause code bloat and one quickly starts to carry around a large number of type arguments, that are only required at some lower levels, but now show up in high level interfaces. To answer your question: Most things in OpenSG (all FieldContainers for example) have a type object, that you can query for the name of the type and also an id.
hm, GeoProperties are the ones that come to mind that already exist in the system and are quite likely to be animated. Let me know if these do not help and you need some containers for experimentation.Sorry but no, they don't help... I need a FieldContainer with some MFields inside...
hm, they do have that, it just is a bit less obvious with the geo properties, given all the template stuff around it ;)Anyways, I've attached a .zip (slightly renamed to get SF to accept the attachment) file with a container that has some S and
MFields, place the files in Source/WindowSystem/GLUT and recompile
OpenSG (let me know if that causes a major problem for you, I can try to
move them to their own lib or so).
Hope it helps,
Carsten
OSGAnimTestContainer.zip.TrickSF
Description: Binary data
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________ Opensg-core mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opensg-core
