|
From: Chris M. <cm...@ve...> - 2001-06-18 18:52:56
|
Hi,
My guess is that your modification to make the scene
rotate about the center of the screen (usually referred
to as "Examine mode") broke the association between
the rendered scene and the visible object computation
used for the visibility culling optimization. The
comment that begins "Hack alert" seems relevant.
At this point, the openvrml project is being run on
sourceforge, where the openvrml-develop mailing list
might be helpful if you continue to work with it.
Good luck,
Chris
----- Original Message -----
From: CAO Shangwen
To: cm...@ve...
Sent: Monday, June 11, 2001 10:29 AM
Subject: a question...
Hello Mr Chris Morley,
I'd thank you for your VRML open source code. I am developing a VRML plugin
which partly based on the open source code. But I found out a problem. Could
you please explain it to me? Thank you very much!
The problem is: why some VRML objects disappeared when I rotate VRML world
about the screen center? The following code concerns the problem and three
pictures are attached in this email.
Best wishes,
CAO Shangwen
void VrmlScene::render(Viewer *viewer)
{
if (d_newView)
{
viewer->resetUserNavigation();
d_newView = false;
}
// Default viewpoint parameters
float position[3] = { 0.0, 0.0, 10.0 };
float orientation[4] = { 0.0, 0.0, 1.0, 0.0 };
float field = 0.785398;
float avatarSize = 0.25;
float visibilityLimit = 0.0;
// since opengl post multiples the matrix, we need to do the user
// navigation transform first. this needs to be fixed so it doesn't
// depend on a special arg to beginObject.
//
// viewer->beginObject(0);
// CAO noted: I removed the sentence to back. Because if VRML screnn does
not rotate around the screen center
VrmlNodeViewpoint *vp = bindableViewpointTop();
if (vp)
{
std::copy(vp->getPosition().get(), vp->getPosition().get() + 3,
position);
std::copy(vp->getOrientation().get(), vp->getOrientation().get() + 4,
orientation);
field = vp->getFieldOfView().get();
vp->inverseTransform(viewer); // put back!
}
VrmlNodeNavigationInfo *ni = bindableNavigationInfoTop();
if (ni)
{
avatarSize = ni->avatarSize()[0];
visibilityLimit = ni->visibilityLimit();
}
// sets the viewpoint transformation
//
viewer->setViewpoint(position, orientation, field, avatarSize,
visibilityLimit);
viewer->beginObject(0); // CAO noticed: To rotate the VRML screen about the
screen center.
//
// Hack alert: Right now the rendering code uses the old-style
// set/unset Transform code, but the culling code accumulates the
// modelview matrix on the core side using modifications to
// VrmlTransform and the new VrmlRenderContext class.
//
// However, that means we need to jump through some hoops to make
// sure that the new modelview transform code exactly shadows the
// old code.
//
double M[4][4]; // the modelview transform
Midentity(M);
if (vp) { // viewpoint is optional
// find the inverse of the transform stack above the viewpoint.
//
vp->inverseTransform(M);
// find where the viewpoint itself points (the viewpoint has its
// own built-in transformation, in addition to the transformations
// of any parent nodes. yes, that is redundant, but that's what the
// vrml97 spec says)
//
double vp_IM[4][4];
vp->getInverseMatrix(vp_IM);
MM(M, vp_IM);
} else {
// if there's no viewpoint, then set us up arbitrarily at 0,0,-10,
// as indicated in the vrml spec (section 6.53 Viewpoint).
//
float t[3] = { 0.0f, 0.0f, -10.0f };
Mtranslation(M, t);
}
// the user can navigate away from the viewpoint. that part is
// handled entirely by the viewer.
//
double UN[4][4];
viewer->getUserNavigation(UN);
double M_tmp[4][4];
Mcopy(M_tmp, M);
MM(M, UN, M_tmp);
VrmlRenderContext rc(VrmlBVolume::BV_PARTIAL, M);
rc.setDrawBSpheres(true);
// Set background.
VrmlNodeBackground *bg = bindableBackgroundTop();
if (bg)
{ // Should be transformed by the accumulated rotations above ...
bg->renderBindable(viewer);
}
else
viewer->insertBackground(); // Default background
// Fog
VrmlNodeFog *f = bindableFogTop();
if (f)
{
viewer->setFog(f->color(), f->visibilityRange(), f->fogType());
}
// Activate the headlight.
// ambient is supposed to be 0 according to the spec...
if ( headlightOn() )
{
float rgb[3] = { 1.0, 1.0, 1.0 };
float xyz[3] = { 0.0, 0.0, -1.0 };
float ambient = 0.3;
viewer->insertDirLight( ambient, 1.0, rgb, xyz );
}
// Do the scene-level lights (Points and Spots)
VrmlNodeList::iterator li, end = d_scopedLights->end();
for (li = d_scopedLights->begin(); li != end; ++li)
{
VrmlNodeLight* x = (*li)->toLight();
if (x) x->renderScoped( viewer );
}
// Render the top level group
d_nodes.render( viewer, rc );
viewer->endObject();
// This is actually one frame late...
d_frameRate = viewer->getFrameRate();
clearModified();
// If any events were generated during render (ugly...) do an update
if (eventsPending())
setDelta( 0.0 );
}
picture 1: before rotate the VRML world, all balls can be seen
picture 2: after rotate the VRML world, three balls disappeared
|