base.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Robot Group Leipzig                             *
00003  *    martius@informatik.uni-leipzig.de                                    *
00004  *    fhesse@informatik.uni-leipzig.de                                     *
00005  *    der@informatik.uni-leipzig.de                                        *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************
00022  *                                                                         *
00023  *  DESCRIPTION                                                            *
00024  *                                                                         *
00025  *   $Log: base.cpp,v $
00026  *   Revision 1.1.2.6  2006/01/12 22:34:06  martius
00027  *   *** empty log message ***
00028  *
00029  *   Revision 1.1.2.5  2006/01/12 14:21:00  martius
00030  *   drawmode, material
00031  *
00032  *   Revision 1.1.2.4  2005/12/13 18:11:13  martius
00033  *   transform primitive added, some joints stuff done, forward declaration
00034  *
00035  *   Revision 1.1.2.3  2005/12/11 23:35:08  martius
00036  *   *** empty log message ***
00037  *
00038  *   Revision 1.1.2.2  2005/12/09 16:54:16  martius
00039  *   camera is woring now
00040  *
00041  *   Revision 1.1.2.1  2005/12/06 17:40:59  martius
00042  *   base class for simulation
00043  *
00044  *                                                                 *
00045  ***************************************************************************/
00046 
00047 #include <iostream>
00048 #include <osg/Node>
00049 #include <osg/Geode>
00050 #include <osg/Geometry>
00051 #include <osg/Texture2D>
00052 #include <osg/TexEnv>
00053 #include <osg/TexGen>
00054 #include <osg/Depth>
00055 #include <osg/StateSet>
00056 #include <osg/ClearNode>
00057 #include <osg/Transform>
00058 #include <osg/MatrixTransform>
00059 #include <osg/Light>
00060 #include <osg/LightSource>
00061 #include <osg/ShapeDrawable>
00062 
00063 #include <osgUtil/CullVisitor>
00064 
00065 #include <osgDB/Registry>
00066 #include <osgDB/ReadFile>
00067 
00068 #include <osgGA/AnimationPathManipulator>
00069 
00070 #include "rendertotexturecallback.h"
00071 #include "base.h"
00072 #include "primitive.h"
00073 
00074 using namespace osg;
00075 
00076 namespace lpzrobots {
00077 
00078 
00079   Group* Base::makeScene(){
00080     // no database loaded so automatically create Ed Levin Park..
00081     root = new Group;
00082     // the base and sky subgraphs go to set the earth sky of the
00083     // model and clear the color and depth buffer for us, by using
00084     // osg::Depth, and setting their bin numbers to less than 0,
00085     // to force them to draw before the rest of the scene.
00086     ClearNode* clearNode = new ClearNode;
00087     
00088     // use a transform to make the sky and base around with the eye point.
00089     osg::Transform* transform = new osg::Transform;//MoveEarthySkyWithEyePointTransform;
00090 
00091     // add the transform to the earth sky.
00092     clearNode->addChild(transform);
00093 
00094     root->addChild(clearNode);
00095 
00096     Group* group = new Group; // create an extra group for the normal scene
00097     
00098     root->addChild(group);
00099 
00100     // transform's value isn't knowm until in the cull traversal so its bounding
00101     // volume can't be determined, therefore culling will be invalid,
00102     // so switch it off, this cause all our paresnts to switch culling
00103     // off as well. But don't worry culling will be back on once underneath
00104     // this node or any other branch above this transform.
00105     transform->setCullingActive(false);
00106 
00107     // add the sky and base layer.
00108     transform->addChild(makeSky());  // bin number -2 so drawn first.
00109     transform->addChild(makeGround()); // bin number -1 so draw second.      
00110     
00111     LightSource* lightSource = makeLights(root->getOrCreateStateSet());
00112     transform->addChild(lightSource);
00113     
00114     // This should bring real shadows, need to be fixed somehow
00115     // ref_ptr<Texture2D> texture = new Texture2D;
00116 //     texture->setInternalFormat(GL_DEPTH_COMPONENT);
00117 //     texture->setShadowComparison(true);
00118 //     texture->setShadowTextureMode(Texture::LUMINANCE);
00119     
00120 //     ref_ptr<TexGen> texGen = new TexGen;
00121 //     texGen->setMode(TexGen::EYE_LINEAR);
00122 //     group->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get(), StateAttribute::ON);
00123 //     group->getOrCreateStateSet()->setTextureAttributeAndModes(0, texGen.get(), StateAttribute::ON);
00124     
00125 //     root->setCullCallback(new RenderToTextureCallback(group, texture.get(), lightSource, texGen.get()));
00126     
00127     return group; 
00128   }
00129 
00130   Node* Base::makeSky() {
00131     // taken from osghangglider example
00132     int i, j;
00133     float lev[] = {-5.0, -1.0, 2.0, 12.0, 30.0, 60.0, 90.0  };
00134     float cc[][4] =
00135       {
00136         { 0.0, 0.0, 0.15 },
00137         { 0.0, 0.0, 0.15 },
00138         { 0.4, 0.4, 0.7 },
00139         { 0.2, 0.2, 0.6 },
00140         { 0.1, 0.1, 0.6 },
00141         { 0.1, 0.1, 0.6 },
00142         { 0.1, 0.1, 0.6 },
00143       };
00144     float x, y, z;
00145     float alpha, theta;
00146     float radius = 1000.0f;
00147     int nlev = sizeof( lev )/sizeof(float);
00148 
00149     Geometry *geom = new Geometry;
00150 
00151     Vec3Array& coords = *(new Vec3Array(19*nlev));
00152     Vec4Array& colors = *(new Vec4Array(19*nlev));
00153     Vec2Array& tcoords = *(new Vec2Array(19*nlev));
00154     
00155     
00156     int ci = 0;
00157 
00158     for( i = 0; i < nlev; i++ )
00159       {
00160         for( j = 0; j <= 18; j++ )
00161           {
00162             alpha = osg::DegreesToRadians(lev[i]);
00163             theta = osg::DegreesToRadians((float)(j*20));
00164 
00165             x = radius * cosf( alpha ) * cosf( theta );
00166             y = radius * cosf( alpha ) * -sinf( theta );
00167             z = radius * sinf( alpha );
00168 
00169             coords[ci][0] = x;
00170             coords[ci][1] = y;
00171             coords[ci][2] = z;
00172 
00173             colors[ci][0] = cc[i][0];
00174             colors[ci][1] = cc[i][1];
00175             colors[ci][2] = cc[i][2];
00176             colors[ci][3] = 1.0;
00177 
00178             tcoords[ci][0] = (float)j/18.0;
00179             tcoords[ci][1] = (float)i/(float)(nlev-1);
00180 
00181             ci++;
00182           }
00183 
00184 
00185       }
00186 
00187     for( i = 0; i < nlev-1; i++ )
00188       {
00189         DrawElementsUShort* drawElements = new DrawElementsUShort(PrimitiveSet::TRIANGLE_STRIP);
00190         drawElements->reserve(38);
00191 
00192         for( j = 0; j <= 18; j++ )
00193           {
00194             drawElements->push_back((i+1)*19+j);
00195             drawElements->push_back((i+0)*19+j);
00196           }
00197 
00198         geom->addPrimitiveSet(drawElements);
00199       }
00200     
00201     geom->setVertexArray( &coords );
00202     geom->setTexCoordArray( 0, &tcoords );
00203 
00204     geom->setColorArray( &colors );
00205     geom->setColorBinding( Geometry::BIND_PER_VERTEX );
00206 
00207 
00208     Texture2D *tex = new Texture2D;
00209     tex->setImage(osgDB::readImageFile("Images/white.rgb"));
00210 
00211     StateSet *dstate = new StateSet;
00212 
00213     dstate->setTextureAttributeAndModes(0, tex, StateAttribute::OFF );
00214     dstate->setTextureAttribute(0, new TexEnv );
00215     dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
00216     dstate->setMode( GL_CULL_FACE, StateAttribute::ON );
00217     
00218 
00219     // clear the depth to the far plane.
00220     osg::Depth* depth = new osg::Depth;
00221     depth->setFunction(osg::Depth::ALWAYS);
00222     depth->setRange(1.0,1.0);   
00223     dstate->setAttributeAndModes(depth,StateAttribute::ON );
00224 
00225     dstate->setRenderBinDetails(-2,"RenderBin");
00226 
00227     geom->setStateSet( dstate );
00228 
00229     Geode *geode = new Geode;
00230     geode->addDrawable( geom );
00231 
00232     geode->setName( "Sky" );
00233 
00234     return geode;
00235   }
00236 
00237   Node* Base::makeGround(){
00238     int i, c;
00239     float theta;
00240     float ir = 1000.0f;
00241 
00242     Vec3Array *coords = new Vec3Array(19);
00243     Vec2Array *tcoords = new Vec2Array(19);
00244     Vec4Array *colors = new Vec4Array(1);
00245 
00246     (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
00247 
00248     c = 0;
00249     (*coords)[c].set(0.0f,0.0f,0.0f);
00250     (*tcoords)[c].set(0.0f,0.0f);
00251     
00252     for( i = 0; i <= 18; i++ )
00253       {
00254         theta = osg::DegreesToRadians((float)i * 20.0);
00255 
00256         (*coords)[c].set(ir * cosf( theta ), ir * sinf( theta ), 0.0f);
00257         (*tcoords)[c].set((*coords)[c][0],(*coords)[c][1]);
00258 
00259         c++;
00260       }
00261 
00262     Geometry *geom = new Geometry;
00263 
00264     geom->setVertexArray( coords );
00265 
00266     geom->setTexCoordArray( 0, tcoords );
00267 
00268     geom->setColorArray( colors );
00269     geom->setColorBinding( Geometry::BIND_OVERALL );
00270 
00271     geom->addPrimitiveSet( new DrawArrays(PrimitiveSet::TRIANGLE_FAN,0,19) );
00272 
00273     Texture2D *tex = new Texture2D;
00274 
00275     tex->setImage(osgDB::readImageFile("Images/ground.rgb"));
00276     tex->setWrap( Texture2D::WRAP_S, Texture2D::REPEAT );
00277     tex->setWrap( Texture2D::WRAP_T, Texture2D::REPEAT );
00278 
00279     StateSet *dstate = new StateSet;
00280     dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
00281     dstate->setTextureAttributeAndModes(0, tex, StateAttribute::ON );
00282 
00283     dstate->setTextureAttribute(0, new TexEnv );
00284 
00285 //     // clear the depth to the far plane.
00286 //     osg::Depth* depth = new osg::Depth;
00287 //     depth->setFunction(osg::Depth::ALWAYS);
00288 //     depth->setRange(1.0,1.0);   
00289 //     dstate->setAttributeAndModes(depth,StateAttribute::ON );
00290 
00291     dstate->setRenderBinDetails(-1,"RenderBin");
00292 
00293 
00294     geom->setStateSet( dstate );
00295 
00296     Geode *geode = new Geode;
00297     geode->addDrawable( geom );
00298     geode->setName( "Ground" );
00299 
00300     // add ODE Ground here
00301     ground = dCreatePlane ( odeHandle.space , 0 , 0 , 1 , 0 );
00302 
00303     return geode;
00304   }
00305 
00306 
00307 LightSource* Base::makeLights(StateSet* stateset)
00308 {
00309   // create a spot light.
00310   Light* light_0 = new Light;
00311   light_0->setLightNum(0);
00312   light_0->setPosition(Vec4(10.0, 0, 20.0, 1.0f));
00313   light_0->setDirection(Vec3(-0.5, 0, -1.0));
00314   light_0->setAmbient(Vec4(0.6f, 0.6f, 0.6f, 1.0f));
00315   light_0->setDiffuse(Vec4(1.0f, 1.0f, 1.0f, 1.0f));
00316   //light_0->setSpotCutoff(60.0f);
00317   //  light_0->setSpotExponent(2.0f);
00318 
00319   LightSource* light_source_0 = new LightSource;        
00320   light_source_0->setLight(light_0);
00321   light_source_0->setLocalStateSetModes(StateAttribute::ON);   
00322   
00323   light_source_0->setStateSetModes(*stateset, StateAttribute::ON);
00324   
00325   return light_source_0;
00326 }
00327 
00328 
00329 /********************************************************************************/
00330 
00331   bool MoveEarthySkyWithEyePointTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const 
00332   {
00333     osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
00334     if (cv)
00335       {
00336         osg::Vec3 eyePointLocal = cv->getEyeLocal();
00337         matrix.preMult(osg::Matrix::translate(eyePointLocal.x(),eyePointLocal.y(),0.0f));
00338       }
00339     return true;
00340   }
00341 
00342   bool MoveEarthySkyWithEyePointTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
00343   {
00344     std::cout<<"computing transform"<<std::endl;
00345     
00346     osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
00347     if (cv)
00348       {
00349         osg::Vec3 eyePointLocal = cv->getEyeLocal();
00350         matrix.postMult(osg::Matrix::translate(-eyePointLocal.x(),-eyePointLocal.y(),0.0f));
00351       }
00352     return true;
00353   }
00354   
00355 
00356 }
00357 
00358 
00359 

Generated on Tue Apr 4 19:05:03 2006 for Robotsystem from Robot Group Leipzig by  doxygen 1.4.5