[cc'ing the core list, as there is an underlying issue in the system]

        Hello Austin,

Austin Baker wrote:
Hello Carsten,

(Rename the attached .cpp file as a .zip file)

I've modified the opensg tutoral "10loading" to demonstrate my
flattening mechanism. In the attached .cpp file (Rename as .zip!) file
are 2 executables (exhibiting both behaviors), the .WRL model file,
and the modified 10loading.cpp.

Thanks! The executables were not necessary, as I don't have easy access to a windows machine anyways, but your efforts in preparing the reproducer are appreciated.

Please find attached a slightly modified file that works for me.
The problem is actually quite easy, but admittedly hard to find and somewhat surprising. I'm not sure if it is feasible to remove this source of surprise.
Anyways, here is the problem:
The Transformation cores in your scene are actually ComponentTransforms, that derive from Transform, but internally store individual transformations instead of just a matrix.
When you set the matrix, with this line:

TransformPtr parent_xform = TransformPtr::dcast(parentPtr->getCore());
beginEditCP(parent_xform);
  parent_xform->setMatrix(worldMatrix);
endEditCP(parent_xform);
The update function of ComponentTransform runs and since no field mask is explicitly given, the assumption is that all fields have changed. Therefore the update function of ComponentTransform recomputes the matrix from the individual components (which are really unchanged) and overwrites the matrix you just set. To prevent this, change the begin/endEditCP calls to contain the field mask of the fields that you really edit, i.e.:

beginEditCP(parent_xfrom, Transform::MatrixFieldMask);
  parent_xform->setMatrix(worldMatrix);
endEditCP(parent_xfrom, Transform::MatrixFieldMask);

        Hope it helps,
                Carsten
// OpenSG Tutorial Example: Loading
//
// This example shows how to load a scene file using OpenSG.
// The supported formats right now are VRML97, OBJ, OFF and RAW, so just
// calling this program with a scene file as a parameter should load the scene
// file.
//

// Headers
#include <OpenSG/OSGGLUT.h>
#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGSimpleGeometry.h>
#include <OpenSG/OSGGLUTWindow.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGAction.h>
#include <OpenSG/OSGTime.h>

// the general scene file loading handler
#include <OpenSG/OSGSceneFileHandler.h>


// Activate the OpenSG namespace
OSG_USING_NAMESPACE

// The SimpleSceneManager to manage simple applications
SimpleSceneManager *mgr;

// forward declaration so we can have the interesting stuff upfront
int setupGLUT( int *argc, char *argv[] );
osg::NodePtr flattenScene(NodePtr node, NodePtr newRoot);
void printSubgraph(NodePtr node, int level);


// helper class to find a named node
// names are handled as simple attachments, get the header for that
#include <OpenSG/OSGSimpleAttachments.h>

// There are two convenience functions for name access: getName() and
// setName(). For details about general attachment handling see the 
// attachments tutorial

class NamedNodeFinder
{
  public:
  
    NamedNodeFinder(void) : _name(), _found() {}

    NodePtr operator() (NodePtr root, std::string name)
    {
        _name=&name;
        _found=NullFC;
        
        traverse(root, osgTypedMethodFunctor1ObjPtrCPtrRef(
                            this, 
                            &NamedNodeFinder::check));
        
        return _found;
    }
 
    static NodePtr find(NodePtr root, std::string name)
    {
        NamedNodeFinder f;      
        
        return f(root,name);
    }
   
  private:
     
    Action::ResultE check(NodePtr& node)
    {
        if(getName(node) && *_name == getName(node))
        {
            _found = node;
            return Action::Quit;
        }

        return Action::Continue;        
    }
 
    NodePtr  _found;
    std::string  *_name;
};

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

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

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

    // load the scene

    NodePtr scene;
      
    scene = SceneFileHandler::the().read("linkingNoMovement.wrl");   

    printSubgraph(scene, 0);

    // Flatten scene:

    std::cerr << std::endl << "flattening scene tree..." << std::endl;

    NodePtr flattened_scene = Node::create();
    GroupPtr group = Group::create();
    
    beginEditCP(flattened_scene, Node::CoreFieldMask | Node::ChildrenFieldMask  
);
    {
        flattened_scene->setCore(group);
    }
    endEditCP  (flattened_scene, Node::CoreFieldMask | Node::ChildrenFieldMask  
);

    // COMMENT OUT flattenScene TO SEE NORMAL BEHAVIOR
    flattenScene(scene,flattened_scene);
    
    std::cerr << "------------------------" << std::endl;
    printSubgraph(flattened_scene, 0);

    // create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // tell the manager what to manage
    mgr->setWindow(gwin );
    
    // SWITCH BELOW TO SEE NORMAL BEHAVIOR
    //mgr->setRoot  (scene);
    mgr->setRoot  (flattened_scene);

    // show the whole scene
    mgr->showAll();

    // GLUT main loop
    glutMainLoop();

    return 0;
}

// Flatten Scene Function:
osg::NodePtr flattenScene(NodePtr node, NodePtr newRoot)
{
  // Get number of children and core
  int numChildren = node->getNChildren();
  NodeCorePtr nodeCore = node->getCore();

  if (numChildren <= 0) // Do we have a leaf node?
  {
    if(nodeCore != NullFC && 
nodeCore->getType().isDerivedFrom(Geometry::getClassType()))
    {
      // save current world matrix of the object
      NodePtr parentPtr = node->getParent()->getParent();
      Matrix worldMatrix = parentPtr->getToWorld();
      
      // move nodes to new root and reset the world matrix
      beginEditCP(newRoot);
        newRoot->addChild(parentPtr);
        TransformPtr parent_xform = TransformPtr::dcast(parentPtr->getCore()); 
        beginEditCP(parent_xform, Transform::MatrixFieldMask); 
          parent_xform->setMatrix(worldMatrix);
        endEditCP(parent_xform, Transform::MatrixFieldMask); 
      endEditCP(newRoot);
    }
  }
  else // Continue Traversing...
  {
    for (int i = numChildren-1; i >= 0; i--) flattenScene(node->getChild(i), 
newRoot);
  }

  // Should not Get To This Point
  return NullFC;
}

//-------------------------------------------------------------------------------------------
// GLUT callback functions
//

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

void update(void)
{
    glutPostRedisplay();
}

// 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(update);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    return winid;
}

void printSubgraph(NodePtr node, int level)
{
  std::string name;
  if (getName(node)) { name = getName(node); }else { name = "-NA-"; }

  NodeCorePtr core = node->getCore();
  if(core != NullFC)
  {
    if (level == 0) std::cerr << "[" << core->getType().getCName() << "]: " << 
name.c_str() << std::endl;
    else if (level == 1) std::cerr << "  [" << core->getType().getCName() << 
"]: " << name.c_str() << std::endl;
    else if (level == 2) std::cerr << "    [" << core->getType().getCName() << 
"]: " << name.c_str() << std::endl;
    else if (level == 3) std::cerr << "      [" << core->getType().getCName() 
<< "]: " << name.c_str() << std::endl;
  }

  //check all children
  for(int i = 0; i < node->getNChildren(); i++) 
printSubgraph(node->getChild(i),level+1);

  return;
}
-------------------------------------------------------------------------
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

Reply via email to