[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