Hello Johannes,
Johannes Brunen wrote:
Unfortunately, I have still problems now
on moving the geometry. I did change the example a little so that I'm i)
able to create two objects and ii) to move them around. Possibly, that
problem is of similar nature as the former one.
Ok, new trial...
thanks, this time the code was inline again (the attachment only came
through ungarbled on the copy you sent directly to me - strange).
Anyways, the problem, as you already suspected, is that the plane
geometry is specified in a different coordinate system than the clip planes:
Somewhat simplified your graph looks like:
scene [Group]
|
geoTrafo [Transform]
|
+----------------+------------------------+
| | |
mat1 [MatGroup] mat2 [MatGroup] mat3 [MatGroup]
| | |
geo [Geo] planeTrafo [Transform] geo [Geo]
|
planeGeo [Geo]
So your plane geometry is in the coordinate system of the real geometry,
but the clip planes are in world coordinates (the beacons of the clip
plane chunks are roots).
You can fix this by adding an InverseTransform above planeTrafo, which
negates all accumulated Transformation so far. If you have the case
where the clip planes are not in world coordinates you would have to add
another Transform below the InverseTransform and above planeTrafo that
*shares* the core with the beacon.
As far as the "overlapping" geometry is concerned, yes the algorithm
gets that wrong. It essentially counts how many triangles are on top of
each other and if the front facing ones of both the box and the torus
are cut away the number is still 2 (there are 2 layers of back facing
triangles on top of each other). To the algorithm that looks like a non
clipped object.
Cheers,
Carsten
// OpenSG example: ClipPlaneCaps
//
// Demonstrates the use of the ClipPlaneChunk, StencilChunk for capping of clipped geometry
#include <vector>
#include <OpenSG/OSGGLUT.h>
#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGSimpleGeometry.h>
#include <OpenSG/OSGPassiveWindow.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGSceneFileHandler.h>
#include <OpenSG/OSGMultiSwitch.h>
#include <OpenSG/OSGMaterialGroup.h>
#include <OpenSG/OSGChunkMaterial.h>
#include <OpenSG/OSGSimpleMaterial.h>
#include <OpenSG/OSGClipPlaneChunk.h>
#include <OpenSG/OSGStencilChunk.h>
#include <OpenSG/OSGInverseTransform.h>
#include <OpenSG/OSGDepthChunk.h>
OSG_USING_NAMESPACE
class FCEditGuard
{
public:
#if OSG_MAJOR_VERSION < 2
FCEditGuard(const FieldContainerPtr& a,
BitVector b = FieldBits::AllFields,
UInt32 c = ChangedOrigin::External)
: obj(a), mask(b), origin(c)
{
beginEditCP(obj, mask, origin);
}
#else
FCEditGuard(const FieldContainerPtr&,
BitVector = FieldBits::AllFields,
UInt32 = ChangedOrigin::External) {}
#endif
~FCEditGuard()
{
#if OSG_MAJOR_VERSION < 2
endEditCP(obj, mask, origin);
#endif
}
private:
#if OSG_MAJOR_VERSION < 2
const FieldContainerPtr& obj;
BitVector mask;
UInt32 origin;
#endif
};
typedef std::vector<NodePtr> VecNodesT;
struct ClipPlaneData
{
Vec4f _equation;
bool _enabled;
};
typedef std::vector<ClipPlaneData> VecClipPlaneData;
struct ClipPlaneDetails {
ClipPlaneChunkPtr _clipPlaneChunk;
NodePtr _planeRootNode;
NodePtr _planeTrafoNode;
MaterialGroupPtr _materialCore;
};
typedef std::vector<ClipPlaneDetails> VecClipPlaneDetailsT;
// global state
VecClipPlaneData vecClipPlaneData;
VecClipPlaneDetailsT vecClipPlaneDetails;
VecNodesT vecGeometries;
SimpleSceneManager *mgr;
NodePtr scene;
// the number of clipping planes supported by the demo
const int iNumClipPlanes = 2;
void createClipPlaneDetails()
{
for (int i = 0; i < iNumClipPlanes; ++i) {
ClipPlaneDetails details;
//
// Create clip plane chunk
//
details._clipPlaneChunk = ClipPlaneChunk::create();
addRefCP(details._clipPlaneChunk);
{
FCEditGuard guard(details._clipPlaneChunk);
details._clipPlaneChunk->setEquation(Vec4f(1,0,0,0));
details._clipPlaneChunk->setEnable(false);
NodePtr beacon = Node::create();
addRefCP(beacon);
details._clipPlaneChunk->setBeacon(beacon);
}
//
// Create plane geometry
//
NodePtr planeGeoNode = makePlane(100.f, 100.f, 128, 128);
Matrix mat;
mat.setIdentity();
TransformPtr transfCore = Transform::create();
{
FCEditGuard guard(transfCore);
transfCore->setMatrix(mat);
}
details._planeTrafoNode = Node::create();
addRefCP(details._planeTrafoNode);
{
FCEditGuard guard(details._planeTrafoNode);
details._planeTrafoNode->setCore(transfCore);
details._planeTrafoNode->addChild(planeGeoNode);
}
details._planeRootNode = Node::create();
InverseTransformPtr invTransCore = InverseTransform::create();
{
FCEditGuard guard(details._planeRootNode);
details._planeRootNode->setCore(invTransCore);
details._planeRootNode->addChild(details._planeTrafoNode);
}
//
// Create stencil material core
//
StencilChunkPtr stencilChunk = StencilChunk::create();
{
FCEditGuard guard(stencilChunk);
stencilChunk->setClearBuffer(1);
stencilChunk->setStencilFunc(GL_NEVER);
stencilChunk->setStencilValue(1);
stencilChunk->setStencilMask(1);
stencilChunk->setStencilOpFail(GL_INVERT);
stencilChunk->setStencilOpZFail(GL_INVERT);
stencilChunk->setStencilOpZPass(GL_INVERT);
}
ChunkMaterialPtr mat1 = ChunkMaterial::create();
{
FCEditGuard guard(mat1);
mat1->addChunk(stencilChunk);
mat1->addChunk(details._clipPlaneChunk);
mat1->setSortKey(2*i + 0);
}
details._materialCore = MaterialGroup::create();
addRefCP(details._materialCore);
{
FCEditGuard guard(details._materialCore);
details._materialCore->setMaterial(mat1);
}
vecClipPlaneDetails.push_back(details);
}
}
void destroyClipPlaneDetails()
{
for (int i = 0; i < iNumClipPlanes; ++i) {
subRefCP(vecClipPlaneDetails[i]._clipPlaneChunk->getBeacon());
subRefCP(vecClipPlaneDetails[i]._clipPlaneChunk);
subRefCP(vecClipPlaneDetails[i]._planeTrafoNode);
subRefCP(vecClipPlaneDetails[i]._planeRootNode);
subRefCP(vecClipPlaneDetails[i]._materialCore);
}
vecClipPlaneDetails.clear();
}
void updateClipPlanes(const VecClipPlaneData& vec)
{
int sz = vec.size();
for (int i = 0; i < iNumClipPlanes; ++i) {
ClipPlaneChunkPtr& clipPlaneChunk = vecClipPlaneDetails[i]._clipPlaneChunk;
FCEditGuard guard(clipPlaneChunk);
clipPlaneChunk->setEnable(false);
if (i < sz) {
const ClipPlaneData& data = vec[i];
clipPlaneChunk->setEquation(data._equation);
clipPlaneChunk->setEnable(data._enabled);
Matrix rotMat;
Vec4f v1(0.f, 0.f, -1.f, 0.f);
Quaternion q(v1, data._equation);
rotMat.setTransform(q);
Matrix mat;
Vec3f v2(0.0f, 0.0f, data._equation[3]);
mat.setTranslate(v2);
mat.multLeft(rotMat);
TransformPtr transformCore = TransformPtr::dcast(vecClipPlaneDetails[i]._planeTrafoNode->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(mat);
}
}
}
}
NodePtr insertGeometry(NodePtr scene, GeometryPtr geo1, const Matrix& matrix)
{
NodePtr geometryNode = Node::create();
{
FCEditGuard guard(geometryNode);
geometryNode->setCore(geo1);
}
VecNodesT vecMaterialNodes1;
VecNodesT vecMaterialNodes2;
for (int i = 0; i < iNumClipPlanes; ++i)
{
NodePtr geomNode = Node::create();
{
FCEditGuard guard(geomNode);
geomNode->setCore(geo1);
}
NodePtr materialNode1 = Node::create();
{
MaterialGroupPtr mgrp1 = vecClipPlaneDetails[i]._materialCore;
FCEditGuard guard(materialNode1);
materialNode1->setCore(mgrp1);
materialNode1->addChild(geomNode);
}
vecMaterialNodes1.push_back(materialNode1);
NodePtr materialNode2 = Node::create();
{
StencilChunkPtr stencilChunk = StencilChunk::create();
{
FCEditGuard guard(stencilChunk);
stencilChunk->setClearBuffer(2);
stencilChunk->setStencilFunc(GL_EQUAL);
stencilChunk->setStencilValue(1);
stencilChunk->setStencilMask(1);
stencilChunk->setStencilOpFail(GL_KEEP);
stencilChunk->setStencilOpZFail(GL_ZERO);
stencilChunk->setStencilOpZPass(GL_ZERO);
}
SimpleMaterialPtr mat2 = SimpleMaterial::create();
{
FCEditGuard guard(mat2);
mat2->setDiffuse(Color3f(0,1,0));
mat2->setSpecular(Color3f(1,1,1));
mat2->setLit(true);
for (int j = 0; j < iNumClipPlanes; ++j) {
if (i != j)
mat2->addChunk(vecClipPlaneDetails[j]._clipPlaneChunk);
}
mat2->addChunk(stencilChunk);
mat2->setSortKey(2*i + 1);
}
MaterialGroupPtr mgrp2 = MaterialGroup::create();
{
FCEditGuard guard(mgrp2);
mgrp2->setMaterial(mat2);
}
FCEditGuard guard(materialNode2);
materialNode2->setCore(mgrp2);
materialNode2->addChild(vecClipPlaneDetails[i]._planeRootNode);
}
vecMaterialNodes2.push_back(materialNode2);
}
NodePtr materialNode3 = Node::create();
{
SimpleMaterialPtr mat3 = SimpleMaterial::create();
{
FCEditGuard guard(mat3);
mat3->setDiffuse(Color3f(1,0,0));
mat3->setSpecular(Color3f(1,1,1));
mat3->setLit(true);
for (int i = 0; i < iNumClipPlanes; ++i) {
mat3->addChunk(vecClipPlaneDetails[i]._clipPlaneChunk);
}
mat3->setSortKey(iNumClipPlanes * 2);
}
MaterialGroupPtr mgrp3 = MaterialGroup::create();
{
FCEditGuard guard(mgrp3);
mgrp3->setMaterial(mat3);
}
FCEditGuard guard(materialNode3);
materialNode3->setCore(mgrp3);
materialNode3->addChild(geometryNode);
}
MultiSwitchPtr selectCore = MultiSwitch::create();
{
FCEditGuard guard(selectCore);
selectCore->setSwitchMode(MultiSwitch::ALL);
}
NodePtr selectNode = Node::create();
{
FCEditGuard guard(selectNode);
selectNode->setCore(selectCore);
for (int i = 0; i < iNumClipPlanes; ++i) {
selectNode->addChild(vecMaterialNodes1[i]);
selectNode->addChild(vecMaterialNodes2[i]);
}
selectNode->addChild(materialNode3);
}
TransformPtr transfCore = Transform::create();
{
FCEditGuard guard(transfCore);
transfCore->setMatrix(matrix);
}
NodePtr trafoNode = Node::create();
{
FCEditGuard guard(trafoNode);
trafoNode->setCore(transfCore);
trafoNode->addChild(selectNode);
}
return trafoNode;
}
// redraw the window
void display(void)
{
// render
mgr->redraw();
// all done, swap
glutSwapBuffers();
}
// 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)
{
static Real32 val0 = 0.f;
static Real32 val1 = 0.f;
static Real32 x1 = 0.f;
static Real32 y1 = 0.f;
static Real32 z1 = 0.f;
static Real32 x2 = 0.f;
static Real32 y2 = 0.f;
static Real32 z2 = 0.f;
switch(k)
{
case '1':
{
vecClipPlaneData[0]._enabled = !vecClipPlaneData[0]._enabled;
updateClipPlanes(vecClipPlaneData);
}
break;
case '2':
{
vecClipPlaneData[1]._enabled = !vecClipPlaneData[1]._enabled;
updateClipPlanes(vecClipPlaneData);
}
break;
case '3':
{
FCEditGuard guard(scene);
if (vecGeometries[0] == NullFC) {
Matrix matrix;
Vec3f v(10.f, 0.f, 15.f);
matrix.setTranslate(v);
vecGeometries[0] = insertGeometry(scene, makeBoxGeo(15, 15, 15, 1, 1, 1), matrix);
scene->addChild(vecGeometries[0]);
} else {
scene->subChild(vecGeometries[0]);
vecGeometries[0] = NullFC;
}
mgr->showAll();
mgr->redraw();
}
break;
case '4':
{
FCEditGuard guard(scene);
if (vecGeometries[1] == NullFC) {
Matrix matrix;
Vec3f v( 0.f, 10.f, 0.f);
matrix.setTranslate(v);
vecGeometries[1] = insertGeometry(scene, makeTorusGeo(2, 6, 8, 16), matrix);
scene->addChild(vecGeometries[1]);
} else {
scene->subChild(vecGeometries[1]);
vecGeometries[1] = NullFC;
}
mgr->showAll();
mgr->redraw();
}
break;
case 'n':
{
val0 -= 0.2;
vecClipPlaneData[0]._equation[3] = val0;
updateClipPlanes(vecClipPlaneData);
}
break;
case 'm':
{
val0 += 0.2;
vecClipPlaneData[0]._equation[3] = val0;
updateClipPlanes(vecClipPlaneData);
}
break;
case ',':
{
val1 -= 0.2;
vecClipPlaneData[1]._equation[3] = val1;
updateClipPlanes(vecClipPlaneData);
}
break;
case '.':
{
val1 += 0.2;
vecClipPlaneData[1]._equation[3] = val1;
updateClipPlanes(vecClipPlaneData);
}
break;
case 'q':
{
x1 -= 0.2f;
Matrix matrix;
Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
matrix.setTranslate(v);
if(vecGeometries[0] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[0]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'w':
{
x1 += 0.2f;
Matrix matrix;
Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
matrix.setTranslate(v);
if(vecGeometries[0] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[0]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'a':
{
y1 -= 0.2f;
Matrix matrix;
Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
matrix.setTranslate(v);
if(vecGeometries[0] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[0]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 's':
{
y1 += 0.2f;
Matrix matrix;
Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
matrix.setTranslate(v);
if(vecGeometries[0] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[0]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'z':
case 'y':
{
z1 -= 0.2f;
Matrix matrix;
Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
matrix.setTranslate(v);
if(vecGeometries[0] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[0]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'x':
{
z1 += 0.2f;
Matrix matrix;
Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
matrix.setTranslate(v);
if(vecGeometries[0] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[0]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'e':
{
x2 -= 0.2f;
Matrix matrix;
Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
matrix.setTranslate(v);
if(vecGeometries[1] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[1]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'r':
{
x2 += 0.2f;
Matrix matrix;
Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
matrix.setTranslate(v);
if(vecGeometries[1] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[1]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'd':
{
y2 -= 0.2f;
Matrix matrix;
Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
matrix.setTranslate(v);
if(vecGeometries[1] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[1]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'f':
{
y2 += 0.2f;
Matrix matrix;
Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
matrix.setTranslate(v);
if(vecGeometries[1] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[1]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'c':
{
z2 -= 0.2f;
Matrix matrix;
Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
matrix.setTranslate(v);
if(vecGeometries[1] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[1]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 'v':
{
z2 += 0.2f;
Matrix matrix;
Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
matrix.setTranslate(v);
if(vecGeometries[1] != NullFC)
{
TransformPtr transformCore = TransformPtr::dcast(vecGeometries[1]->getCore());
{
FCEditGuard guard(transformCore);
transformCore->setMatrix(matrix);
}
}
}
break;
case 27: exit(1);
}
}
int main(int argc, char **argv)
{
osgInit(argc,argv);
// GLUT init
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE);
glutCreateWindow("OpenSG");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
PassiveWindowPtr pwin=PassiveWindow::create();
pwin->init();
// create the SimpleSceneManager helper
mgr = new SimpleSceneManager;
// create the window and initial camera/viewport
mgr->setWindow(pwin);
//
// We need 3 material groups for the clip plane capping trick:
//
// scene
// |
// +--------------------+--------------------+
// | | |
// group1 (mat1) group2 (mat2) group3 (mat3)
// | | |
// geometry (geo1) geometry (geo2) geometry (geo1)
//
// geo1 : actual geometry to draw
// geo2 : plane geometry coincident with the clip plane
//
// mat1 : has a stencil chunk that clears the stencil buffer first, than does the inversion, and has
// a clip plane chunk that enables one clip plane. Sortkey 0.
// mat2 : has a stencil chunk and settings for drawing the clip plane geometry. All clip planes but the
// one coincident with the plane are activated. Sortkey 1.
// mat3 : the material used for the actual geometry. All clip planes are activated. Sortkey 3.
//
// For each active clip plane copies of the left two branches need to be added.
//
//
// Implementation details:
// For each clipplane we provide a ClipPlaneChunk, a MaterialGroup mat1 and the plane geometry geo2
// conveniently in a vector of type VecClipPlaneDetailsT. The next function call initializes this
// data structure. Later on, we provide actual details for the vector elements.
//
createClipPlaneDetails();
scene = Node::create();
{
FCEditGuard guard(scene);
scene->setCore(Group::create());
}
vecGeometries.push_back(NullFC);
vecGeometries.push_back(NullFC);
//
// Build concrete clipping planes
//
ClipPlaneData data1;
ClipPlaneData data2;
data1._equation = Vec4f(0,0,1,0);
data1._enabled = true;
data2._equation = Vec4f(1,0,0,0);
data2._enabled = false;
vecClipPlaneData.push_back(data1);
vecClipPlaneData.push_back(data2);
updateClipPlanes(vecClipPlaneData);
// tell the manager what to manage
mgr->setRoot(scene);
// show the whole scene
mgr->showAll();
mgr->redraw();
pwin->dumpExtensions();
// GLUT main loop
glutMainLoop();
destroyClipPlaneDetails();
return 0;
}
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users