Aron Bierbaum wrote:
> I had some success with the following path. It appears that my problem
> came from the fact that I was not getting the correct value from
> ::VRMLGenericAtt::getClassType(). It was returning the parent class
> static _type variable. Things seem to work better if I create a new
> ClassType in DynamicAttachmentMixin.

yes, that is one part, the others are a mistake in getType (- instead of
+ used) and stub implementations of editDynamicField (see the attached
patch).
And I found the example again (also attached). It's easiest to get
working by just putting it into Source/WindowSystem/GLUT (it does not
belong there but that lib is small and links fast and the example uses
glut and that's certainly available in that lib ;) ).

> Is there some reason that this
> was removed from the code in OpenSG 2.0? Or did it just need to be
> ported?

I think the DynamicAttachment simply was not quite finished and since
they are not heavily used, nobody noticed.


        Carsten
Index: Source/System/FieldContainer/Mixins/OSGDynamicAttachmentMixin.inl
===================================================================
--- Source/System/FieldContainer/Mixins/OSGDynamicAttachmentMixin.inl	(revision 354)
+++ Source/System/FieldContainer/Mixins/OSGDynamicAttachmentMixin.inl	(working copy)
@@ -38,6 +38,19 @@
 
 OSG_BEGIN_NAMESPACE
 
+template <class AttachmentDescT>
+typename DynFieldAttachment<AttachmentDescT>::TypeObject
+    DynFieldAttachment<AttachmentDescT>::_type(
+        true,
+        Desc::getTypeName(),
+        Desc::getParentTypeName(),
+        Desc::getGroupName(),
+        0,
+        (PrototypeCreateF) &Self::createEmpty,
+        NULL,
+        NULL,
+        true);
+
 template <class AttachmentDescT> inline
 typename DynFieldAttachment<AttachmentDescT>::TypeObject &
     DynFieldAttachment<AttachmentDescT>::getType(void)
@@ -78,13 +91,13 @@
             fieldP = fieldDesc.createField();
 
             if(_dynFieldsV.size() <=
-               returnValue - Inherited::NextFieldId)
+               returnValue + Inherited::NextFieldId)
             {
-                _dynFieldsV.resize((returnValue -
+                _dynFieldsV.resize((returnValue +
                                     Inherited::NextFieldId) + 1);
             }
 
-            _dynFieldsV[returnValue - Inherited::NextFieldId] = fieldP;
+            _dynFieldsV[returnValue + Inherited::NextFieldId] = fieldP;
         }
     }
 
@@ -98,7 +111,7 @@
     {
         std::vector<Field *>::iterator vIt = _dynFieldsV.begin();
 
-        vIt += fieldId - Inherited::NextFieldId;
+        vIt += fieldId + Inherited::NextFieldId;
 
         if(vIt != _dynFieldsV.end())
         {
@@ -120,8 +133,8 @@
 Field *DynFieldAttachment<AttachmentDescT>::editDynamicField(
     UInt32 index) 
 {
-    return NULL;
-//    Field *returnValue = _dynFieldsV[index - Inherited::NextFieldId];
+//    return NULL;
+    Field *returnValue = _dynFieldsV[index + Inherited::NextFieldId];
 }
 
 template <class AttachmentDescT> inline
@@ -147,7 +160,18 @@
 Field *DynFieldAttachment<AttachmentDescT>::editDynamicFieldByName(
     const Char8  *szName) 
 {
-    return NULL;
+    const FieldDescriptionBase *descP = NULL;
+
+    descP = _localType.getFieldDesc(szName);
+
+    if(descP != NULL)
+    {
+        return descP->editField(*this);
+    }
+    else
+    {
+        return NULL;
+    }
 }
 
 template <class AttachmentDescT> inline
Index: Source/System/FieldContainer/Mixins/OSGDynamicAttachmentMixin.h
===================================================================
--- Source/System/FieldContainer/Mixins/OSGDynamicAttachmentMixin.h	(revision 354)
+++ Source/System/FieldContainer/Mixins/OSGDynamicAttachmentMixin.h	(working copy)
@@ -67,6 +67,8 @@
 
   public:
 
+    typedef          AttachmentDescT                      Desc;
+
     typedef typename AttachmentDescT::Parent              Inherited;
     typedef typename AttachmentDescT::Parent              ParentContainer;
 
@@ -137,9 +139,10 @@
     /*! \name                      Member                                  */
     /*! \{                                                                 */
 
-    TypeObject           _localType;
+    static TypeObject           _type;
+           TypeObject           _localType;
 
-    std::vector<Field *> _dynFieldsV;
+           std::vector<Field *> _dynFieldsV;
 
     /*! \}                                                                 */
     /*---------------------------------------------------------------------*/
Index: Source/System/Image/OSGImageGenericAtt.h
===================================================================
--- Source/System/Image/OSGImageGenericAtt.h	(revision 354)
+++ Source/System/Image/OSGImageGenericAtt.h	(working copy)
@@ -81,9 +81,9 @@
     typedef FieldContainerAttachment    Parent;
     typedef FieldContainerAttachmentPtr ParentPtr;
 
-    static const Char8 *getTypeName      (void) { return "ImageGenericAtt"; }
-    static const Char8 *getParentTypeName(void) { return "Attachment";      }
-    static const Char8 *getGroupName     (void) { return "ImageGenAtt";     }
+    static const Char8 *getTypeName      (void) { return "ImageGenericAtt";          }
+    static const Char8 *getParentTypeName(void) { return "FieldContainerAttachment"; }
+    static const Char8 *getGroupName     (void) { return "ImageGenericAtt";          }
 
     static InitContainerF         getInitMethod(void) { return NULL; }
 
// OpenSG Tutorial Example: DynamicAttachment
//
// This example shows how to use the DynamicAttachment to store information
// about a scene in its root node.
// Here we will restrict ourselves to things that are already present in the
// scene (we will collect geometries and the transformations), but
// a similar approach can be used to keep data associated to a scene that is
// not currently in use.

// Headers
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGSimpleSceneManager.h>
#include <OSGSceneFileHandler.h>
#include <OSGMaterial.h>
#include <OSGTransform.h>
#include <OSGDynamicAttachmentMixin.h>
#include <OSGAction.h>

// needed for traversal state object binding
#include <boost/bind.hpp>

// Activate the OpenSG namespace
OSG_USING_NAMESPACE

// SimpleSceneManager to manage simple applications
SimpleSceneManager *_mgr = NULL;

// Scene root node.
NodePtr _scene = NullFC;

// forward declaration so we can have the interesting stuff upfront
int setupGLUT(int *argc, char *argv[]);

// start by building a Descriptor for the new Attachment.
struct SceneInfoAttachmentDesc
{
    typedef FieldContainerAttachment    Parent;
    typedef FieldContainerAttachmentPtr ParentPtr;

    static const Char8 *getTypeName      (void) { return "SceneInfoAttachment";      }
    static const Char8 *getParentTypeName(void) { return "FieldContainerAttachment"; }
    static const Char8 *getGroupName     (void) { return "SceneInfoAttachment";      }

    static InitContainerF         getInitMethod(void) { return NULL; }

    static FieldDescriptionBase **getDesc      (void) { return NULL; }
};

// Give the Attachment and pointer a simpler name.
typedef DynFieldAttachment<SceneInfoAttachmentDesc>  SceneInfoAttachment;
typedef SceneInfoAttachment::ObjPtr                  SceneInfoAttachmentPtr;

#if 0
// ***
// I think this is not required - I don't want to have fields that hold
// SceneInfoAttachmentPtr
OSG_BEGIN_NAMESPACE
// specialize FieldTraits for SceneInfoAttachmentPtr fields.
template <>
struct FieldTraits<SceneInfoAttachmentPtr> :
    public FieldTraitsFCPtrBase<SceneInfoAttachmentPtr>
{
    static  DataType                            _type;
    typedef FieldTraits<SceneInfoAttachmentPtr>  Self;

    enum                            { Convertible = Self::NotConvertible };

    static DataType &getType (void) { return _type;                      }

    static Char8    *getSName(void) { return "SFSceneInfoAttachmentPtr";     }
    static Char8    *getMName(void) { return "MFSceneInfoAttachmentPtr";     }
};

DataType FieldTraits<SceneInfoAttachmentPtr>::_type("SceneInfoAttachmentPtr",
                                                    "AttachmentPtr"          );

OSG_END_NAMESPACE
//
// ***
#endif

// A traversal state object
class SceneInfoCollector
{
public:
    SceneInfoCollector(SceneInfoAttachmentPtr pSIA);

    Action::ResultE enter(NodePtrConstArg node);

private:
    void addGeometry (GeometryPtr  pGeo  );
    void addTransform(TransformPtr pTrans);

    SceneInfoAttachmentPtr _pSIA;
};

// Constructor - just store the attachment ptr
SceneInfoCollector::SceneInfoCollector(SceneInfoAttachmentPtr pSIA)
    : _pSIA(pSIA)
{
}

// Traversal "callback" function
// If a Geometry core is found addGeometry is called
// If a Transform core is found addTransform is called
Action::ResultE
SceneInfoCollector::enter(NodePtrConstArg node)
{
    SINFO << "SceneInfoCollector::enter" << endLog;

    NodeCorePtr core = node->getCore();

    SINFO << "Core type: " << core->getType().getCName() << endLog;

    if(core->getType().isDerivedFrom(Geometry::getClassType()))
    {
        addGeometry(cast_dynamic<GeometryPtr>(core));
    }
    else if(core->getType().isDerivedFrom(Transform::getClassType()))
    {
        addTransform(cast_dynamic<TransformPtr>(core));
    }

    return Action::Continue;
}

void
SceneInfoCollector::addGeometry(GeometryPtr pGeo)
{
    SINFO << "SceneInfoCollector::addGeometry" << endLog;

    Field* field = _pSIA->editDynamicFieldByName("geometries");

    // field does not exist yet
    if(field == NULL)
    {
        FieldDescriptionBase* fDescGeometries =
            new MFGeometryPtr::Description(
                MFGeometryPtr::getClassType(),
                "geometries",
                "List of geometries",
                0,
                0,
                reinterpret_cast<FieldIndexEditMethodSig>(
                    &SceneInfoAttachment::editDynamicField),
                reinterpret_cast<FieldIndexGetMethodSig> (
                    &SceneInfoAttachment::getDynamicField),
                false,
                Field::MFDefaultFlags);

        UInt32 fieldId = _pSIA->addField(*fDescGeometries);

        if(fieldId == 0)
        {
            SWARNING << "SceneInfoCollector::addGeometry: addField failed"
                     << endLog;
        }

        field          = _pSIA->editDynamicField(fieldId);
    }

    MFGeometryPtr* geoField = static_cast<MFGeometryPtr*>(field);

    if(geoField != NULL)
    {
        geoField->push_back(pGeo);
    }
    else
    {
        SWARNING << "SceneInfoCollector::addGeometry: could not add to field."
                 << endLog;
    }
}

void
SceneInfoCollector::addTransform(TransformPtr pTrans)
{
    SINFO << "SceneInfoCollector::addTransform" << endLog;

    Field* field = _pSIA->editDynamicFieldByName("transforms");

    // field does not exist yet
    if(field == NULL)
    {
        FieldDescriptionBase* fDescTransforms =
            new MFTransformPtr::Description(
                MFTransformPtr::getClassType(),
                "transforms",
                "List of transformations",
                0,
                0,
                reinterpret_cast<FieldIndexEditMethodSig>(
                    &SceneInfoAttachment::editDynamicField),
                reinterpret_cast<FieldIndexGetMethodSig> (
                    &SceneInfoAttachment::getDynamicField),
                false,
                Field::MFDefaultFlags);

        UInt32 fieldId = _pSIA->addField(*fDescTransforms);

        if(fieldId == 0)
        {
            SWARNING << "SceneInfoCollector::addTransform: addField failed"
                     << endLog;
        }

        field          = _pSIA->editDynamicField(fieldId);
    }

    MFTransformPtr* transField = static_cast<MFTransformPtr*>(field);

    if(transField != NULL)
    {
        transField->push_back(pTrans);
    }
    else
    {
        SWARNING << "SceneInfoCollector::addTransform: could not add to field."
                 << endLog;
    }
}

void
printSIA(SceneInfoAttachmentPtr pSIA)
{
    SLOG << "printSIA" << endLog;

    if(pSIA == NullFC)
    {
        SWARNING << "printSIA: pSIA == NullFC" << endLog;
        return;
    }

    for(UInt32 i = 1; i <= pSIA->getType().getNumFieldDescs(); ++i)
    {
        FieldDescriptionBase *pFieldDesc = pSIA->getFieldDescription(i);
        const Field          *pField     = pSIA->getDynamicField(i);

        SLOG << "field: " << i
             << " name: " << pFieldDesc->getCName()
             << " type: " << pFieldDesc->getFieldType().getCName()
             << endLog;
    }
}

// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // load the given scene
    if(argc < 2)
    {
        SWARNING << "No scene file given, using a dummy scene." << endLog;

        _scene = makeTorus(.5, 2, 16, 16);
    }
    else
    {
        _scene = SceneFileHandler::the()->read(argv[1]);
    }

    // create the attachment.
    SceneInfoAttachmentPtr pSIA = SceneInfoAttachment::create();

    // dump to make sure the attachment is alive
    pSIA->dump();

    // add the attachment to the scene root
    _scene->addAttachment(pSIA);

    // traversal state object
    SceneInfoCollector sic(pSIA);

    // traverse the scene and collect info in the attachment.
    traverse(_scene, boost::bind(&SceneInfoCollector::enter, &sic, _1));

    // notify system of changed fields and cause update of dependent data.
    commitChanges();

    pSIA->dump();
    printSIA(pSIA);

    // the connection between GLUT and OpenSG
    GLUTWindowPtr gwin= GLUTWindow::create();
    gwin->setId(winid);
    gwin->init();

    // create the SimpleSceneManager helper
    _mgr = new SimpleSceneManager;

    // tell the manager what to manage
    _mgr->setWindow(gwin  );
    _mgr->setRoot  (_scene);

    // notify system of changed fields and cause update of dependent data.
    commitChanges();

    // GLUT main loop
    glutMainLoop();

    return 0;
}

//
// GLUT callback functions
//

// redraw the window
void display(void)
{
    _mgr->idle();
    _mgr->redraw();
}

// react to size changes
void reshape(int w, int h)
{
    _mgr->resize(w, h);
    glutPostRedisplay();
}

// react to mouse button presses
void mouse(int button, int state, int x, int y)
{

    if (state)
        _mgr->mouseButtonRelease(button, x, y);
    else
        _mgr->mouseButtonPress(button, x, y);

    glutPostRedisplay();
}

// react to mouse motions with pressed buttons
void motion(int x, int y)
{

    _mgr->mouseMove(x, y);
    glutPostRedisplay();
}

// react to keys
void keyboard(unsigned char k, int , int )
{
    switch(k)
    {
        case 27:
        {
            OSG::osgExit();
            exit(0);
        }
        break;

        case 'f':
        {
            _mgr->setNavigationMode(Navigator::FLY);
        }
        break;

        case 't':
        {
            _mgr->setNavigationMode(Navigator::TRACKBALL);
        }
        break;
    }
}

// setup the GLUT library which handles the windows for us
int setupGLUT(int *argc, char *argv[])
{
    glutInit(argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

    int winid = glutCreateWindow("OpenSG");

    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    return winid;
}
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to