Hi,
I'm creating a Scene Graph wich uses multiple reflections, my problem is that
for some reason when there are suposed to be 9 reflections of the object, it
only shows 3, and 2 of those 3 aren't suposed to look like that, at first I
tought it was an error in the code, but when I show 3 reflections at a time
they look like they should...
Here's the code, and thanks for the help...
Carlos Nava
#include <osg/Notify>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/PolygonMode>
#include <osg/LineWidth>
#include <osg/Math>
#include <osg/State>
#include <osgUtil/Optimizer>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgText/Font>
#include <osgText/Text>
#include <osgSim/OverlayNode>
#include <osgProducer/Viewer>
#include <sstream>
osg::MatrixTransform* reflexion(const osg::Vec4& plano, const osg::Vec3& centro)
{
float angulo;
float angulo2;
float dist;
float deltax;
if (atan2f(plano.z(),plano.x())>osg::PI_2)
{
angulo2=osg::PI-atan2f(plano.x(),plano.z());
angulo=angulo2-osg::PI_2;
dist=-centro.y()*plano.y()-centro.z()*plano.z()-plano.w()-centro.x();
if (angulo2>osg::PI_4)
{
deltax=dist*(1-cosf(angulo2*2));
}
else
{
deltax=dist*cosf(angulo2*2);
}
}
else
{
angulo2=osg::PI-atan2f(plano.x(),plano.z());
angulo=osg::PI_2-angulo2;
dist=centro.x()+centro.y()*plano.y()+centro.z()*plano.z()+plano.w();
if (angulo2>osg::PI_4)
{
deltax=-dist*(1-cosf(angulo2*2));
}
else
{
deltax=-dist*cosf(angulo2*2);
}
}
osg::MatrixTransform* trans2 = new osg::MatrixTransform;
trans2->setDataVariance(osg::Object::STATIC);
trans2->setMatrix(osg::Matrix::translate(-centro)*
osg::Matrix::scale(-1.0,1.0,1.0)*
osg::Matrix::rotate(osg::inRadians(angulo*2),0.0f,1.0f,0.0f)*
osg::Matrix::translate(centro)*
osg::Matrix::translate(osg::Vec3(centro.x()+deltax, centro.y(),
centro.z+dist*sinf(2*angulo2))));
return trans2;
}
osg::MatrixTransform* refbase(const osg::Vec3& centro,float base)
{
float dist;
dist=centro.z()-base;
osg::MatrixTransform* trans2 = new osg::MatrixTransform;
trans2->setDataVariance(osg::Object::STATIC);
trans2->setMatrix(osg::Matrix::translate(-centro)*
osg::Matrix::scale(1.0,1.0,-1.0)*
osg::Matrix::translate(centro)*
osg::Matrix::translate(osg::Vec3(0.0,
0.0,-dist*2)));
return trans2;
}
osg::Node* createMirrors(float xMin,float xMax,float zMin,float zMax,float y)
{
// set up the Geometry.
osg::Geometry* geom = new osg::Geometry;
osg::Vec3Array* coords = new osg::Vec3Array();
coords->push_back( osg::Vec3( 0,0,zMax) ); // front top
coords->push_back( osg::Vec3(xMin,0,zMin) ); // front left
coords->push_back( osg::Vec3(xMax,0,zMin) ); // front right
coords->push_back( osg::Vec3( 0,y,zMax) ); // back top
coords->push_back( osg::Vec3(xMin,y,zMin) ); // back left
coords->push_back( osg::Vec3(xMax,y,zMin) ); // back right
geom->setVertexArray(coords);
osg::DrawElementsUInt* espejoBase =
new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
espejoBase->push_back(4);
espejoBase->push_back(5);
espejoBase->push_back(2);
espejoBase->push_back(1);
geom->addPrimitiveSet(espejoBase);
osg::DrawElementsUInt* espejoIzq =
new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
espejoIzq->push_back(1);
espejoIzq->push_back(0);
espejoIzq->push_back(3);
espejoIzq->push_back(4);
geom->addPrimitiveSet(espejoIzq);
osg::DrawElementsUInt* espejoDer =
new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
espejoDer->push_back(2);
espejoDer->push_back(5);
espejoDer->push_back(3);
espejoDer->push_back(0);
geom->addPrimitiveSet(espejoDer);
/* osg::Vec3Array* norms = new osg::Vec3Array(1);
(*norms)[0].set(0.0f,-1.0f,0.0f);
geom->setNormalArray(norms);
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
*/
osg::Vec4Array* colours = new osg::Vec4Array(1);
(*colours)[0].set(0.0f,0.0f,0.0,1.0f);
geom->setColorArray(colours);
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::Geode* geode = new osg::Geode;
geode->addDrawable(geom);
return geode;
}
osg::Vec4 plano(const osg::Vec3& x1, const osg::Vec3& x2,const osg::Vec3& x3)
{
osg::Vec4 y1(x1.y(),x1.z(),1.0f,-x1.x());
osg::Vec4 y2(x2.y(),x2.z(),1.0f,-x2.x());
osg::Vec4 y3(x3.y(),x3.z(),1.0f,-x3.x());
osg::Vec4 Z;
osg::Vec4 res;
if (y1.x()==0)
{
if (y2.x()==0)
{
if(y3.x()!=0)
{
Z=y1;
y1=y3;
y3=Z;
y1=y1/y1.x();
y2=y2-y1*y2.x();
y3=y3-y1*y3.x();
}
else
{
res.x()=0;
res.y()=1;
res.z()=0;
res.w()=0;
}
}
else {
Z=y1;
y1=y2;
y2=Z;
y1=y1/y1.x();
y2=y2-y1*y2.x();
y3=y3-y1*y3.x();
}
}
else
{
y1=y1/y1.x();
y2=y2-y1*y2.x();
y3=y3-y1*y3.x();
}
if (y2.y()==0)
{
if(y3.y()!=0)
{
Z=y2;
y2=y3;
y3=Z;
y2=y2/y2.y();
y1=y1-y2*y1.y();
y3=y3-y2*y3.y();
}
else
{
res.x()=0;
res.y()=0;
res.z()=1;
res.w()=0;
}
}
else
{
y2=y2/y2.y();
y1=y1-y2*y1.y();
y3=y3-y2*y3.y();
}
y3=y3/y3.z();
y1=y1-y3*y1.z();
y2=y2-y3*y2.z();
res.x()=1;
res.y()=y1.w();
res.z()=y2.w();
res.w()=y3.w();
return res;
}
osg::Node* createCaleidoscope()
{
osg::Node* model = osgDB::readNodeFile("box_grn.osg");
// calculate where to place the mirrors according to the
// loaded models bounding sphere.
const osg::BoundingSphere& bs = model->getBound();
osg::ref_ptr<osg::PositionAttitudeTransform> centro(new
osg::PositionAttitudeTransform);
centro->setPosition(osg::Vec3(-bs.center().x(),-bs.center().y(),-bs.center().z()));
centro->addChild(model);
const osg::BoundingSphere& bsc = centro->getBound();
float escala = 2.0;
float xMin = -bsc.radius()*(1+escala)/tanf(osg::DegreesToRadians(60.0));
float xMax = +bsc.radius()*(1+escala)/tanf(osg::DegreesToRadians(60.0));
float zMin = -bsc.radius();
float zMax = +bsc.radius()*escala;
float y = -bsc.radius()*10.5;
osg::Group* rootNode = new osg::Group;
osg::Node* mirrors = createMirrors(xMin,xMax,zMin,zMax,y);
osg::StateSet* state = mirrors->getOrCreateStateSet();
osg::PolygonMode* pm = new osg::PolygonMode(
osg::PolygonMode::FRONT,
osg::PolygonMode::LINE);
state->setAttributeAndModes(pm);
osg::LineWidth*lw = new osg::LineWidth(1.f);
state->setAttribute(lw);
osg::Vec4 plano1 =
plano(osg::Vec3(0.0,0.0,zMax),osg::Vec3(xMax,0.0,zMin),osg::Vec3(0.0,y,zMax));
osg::Vec4 plano2 =
plano(osg::Vec3(0.0,0.0,zMax),osg::Vec3(xMin,0.0,zMin),osg::Vec3(0.0,y,zMax));
osg::MatrixTransform* refder1 = reflexion(plano1,bsc.center());
refder1->addChild(centro.get());
const osg::BoundingSphere& bsd1 = refder1->getBound();
rootNode->addChild(refder1);
osg::MatrixTransform* refizq1 = reflexion(plano2,bsc.center());
refizq1->addChild(centro.get());
const osg::BoundingSphere& bsi1 = refizq1->getBound();
rootNode->addChild(refizq1);
osg::MatrixTransform* refbas1 = refbase(bsc.center(),zMin);
refbas1->addChild(centro.get());
const osg::BoundingSphere& bsb1 = refbas1->getBound();
rootNode->addChild(refbas1);
osg::MatrixTransform* refder2 = reflexion(plano1,bsi1.center());
refder2->addChild(refizq1);
osg::MatrixTransform* refder3 = reflexion(plano1,bsb1.center());
refder3->addChild(refbas1);
osg::MatrixTransform* refizq2 = reflexion(plano2,bsd1.center());
refizq2->addChild(refder1);
osg::MatrixTransform* refizq3 = reflexion(plano2,bsb1.center());
refizq3->addChild(refbas1);
osg::MatrixTransform* refbas2 = refbase(bsd1.center(),zMin);
refbas2->addChild(refder1);
osg::MatrixTransform* refbas3 = refbase(bsi1.center(),zMin);
refbas3->addChild(refizq1);
/* const osg::BoundingSphere& bs2 = trans2->getBound();
osg::Geode* geode = new osg::Geode;
osgText::Font* font = osgText::readFontFile("fonts/arial.ttf");
osg::Vec4 layoutColor(1.0f,1.0f,1.0f,1.0f);
float layoutCharacterSize = 10.0f;
std::ostringstream os;
// os<<"("<<osg::RadiansToDegrees(angulo2)<<"º)";
os<<"("<<miplano.x()<<","<<miplano.y()<<","<<miplano.z()<<","<<miplano.w()<<")";
osgText::Text* text = new osgText::Text;
text->setFont(font);
text->setColor(layoutColor);
text->setCharacterSize(layoutCharacterSize);
text->setPosition(osg::Vec3(0,y,0));
text->setText(os.str());
text->setLayout(osgText::Text::LEFT_TO_RIGHT);
geode->addDrawable(text);
rootNode->addChild(geode);
*/
rootNode->addChild(centro.get());
rootNode->addChild(mirrors);
rootNode->addChild(refder2);
rootNode->addChild(refizq2);
rootNode->addChild(refbas2);
rootNode->addChild(refder3);
rootNode->addChild(refizq3);
rootNode->addChild(refbas3);
return rootNode;
}
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
// set up the usage document, in case we need to print out how to use this
program.
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+"
is the example which demonstrates use of osg::AnimationPath and
UpdateCallbacks for adding animation to your scenes.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+"
[options] filename ...");
arguments.getApplicationUsage()->addCommandLineOption("-h or
--help","Display this information");
// initialize the viewer.
osgProducer::Viewer viewer(arguments);
// set up the value with sensible default event handlers.
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
// get details on keyboard and mouse bindings used by the viewer.
viewer.getUsage(*arguments.getApplicationUsage());
// if user request help write it out to cout.
if (arguments.read("-h") || arguments.read("--help"))
{
arguments.getApplicationUsage()->write(std::cout);
return 1;
}
bool overlay = false;
while (arguments.read("--overlay")) overlay = true;
// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();
// report any errors if they have occured when parsing the program aguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
osg::Node* rootNode = createCaleidoscope();
osgUtil::Optimizer optimizer;
optimizer.optimize(rootNode);
viewer.setSceneData(rootNode);
viewer.realize();
while( !viewer.done() )
{
viewer.sync();
viewer.update();
viewer.frame();
}
viewer.sync();
viewer.cleanup_frame();
viewer.sync();
return 0;
}
---------------------------------
¡Sé un mejor fotógrafo!
Perfecciona tu técnica y encuentra las mejores fotos.
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org