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

Reply via email to