psycho-objectworld.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-objectworld.C Create an object world */
00002 
00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00004 // by the University of Southern California (USC) and the iLab at USC.  //
00005 // See http://iLab.usc.edu for information about this project.          //
00006 // //////////////////////////////////////////////////////////////////// //
00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00009 // in Visual Environments, and Applications'' by Christof Koch and      //
00010 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00011 // pending; application number 09/912,225 filed July 23, 2001; see      //
00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00013 // //////////////////////////////////////////////////////////////////// //
00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00015 //                                                                      //
00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00017 // redistribute it and/or modify it under the terms of the GNU General  //
00018 // Public License as published by the Free Software Foundation; either  //
00019 // version 2 of the License, or (at your option) any later version.     //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00024 // PURPOSE.  See the GNU General Public License for more details.       //
00025 //                                                                      //
00026 // You should have received a copy of the GNU General Public License    //
00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00029 // Boston, MA 02111-1307 USA.                                           //
00030 // //////////////////////////////////////////////////////////////////// //
00031 // Primary maintainer for this file: Dan Parks <danielfp@usc.edu>
00032 // $HeadURL$
00033 // $Id$
00034 
00035 
00036 #include "GUI/ViewPort3D.H"
00037 #include "GUI/SuperQuadric.H"
00038 #include "Util/log.H"
00039 #include "Util/WorkThreadServer.H"
00040 #include "Util/JobWithSemaphore.H"
00041 #include "Component/ModelManager.H"
00042 #include "Raster/GenericFrame.H"
00043 #include "Image/Layout.H"
00044 #include "Image/MatrixOps.H"
00045 #include "Image/DrawOps.H"
00046 #include "GUI/DebugWin.H"
00047 #include "Media/FrameSeries.H"
00048 #include "Transport/FrameInfo.H"
00049 #include <stdlib.h>
00050 #include <math.h>
00051 #include <rutz/rand.h>
00052 #include <nub/object.h>
00053 
00054 class CartesianPosition
00055 {
00056 protected:
00057   std::vector<float> itsPos;
00058 public:
00059   CartesianPosition(const float x, const float y, const float z, const float roll, const float pitch, const float yaw)
00060   {
00061     itsPos = std::vector<float>(6);
00062     itsPos[0]=x; itsPos[1]=y; itsPos[2]=z;
00063     itsPos[3]=roll; itsPos[4]=pitch; itsPos[5]=yaw;
00064   }
00065 
00066   inline const float& operator[](const uint lev) const;
00067   inline float& operator[](const uint lev);
00068   inline CartesianPosition& operator=(const CartesianPosition& pos);
00069 
00070   inline size_t size() { return itsPos.size(); }
00071 
00072 };
00073 
00074 
00075 inline const float& CartesianPosition::operator[](const uint lev) const
00076 {
00077   ASSERT(lev>=0 && lev <=6);
00078   return itsPos[lev];
00079 }
00080 
00081 inline float& CartesianPosition::operator[](const uint lev)
00082 {
00083   ASSERT(lev>=0 && lev <=6);
00084   return itsPos[lev];
00085 }
00086 
00087 inline CartesianPosition& CartesianPosition::operator=(const CartesianPosition& pos)
00088 {
00089   itsPos = pos.itsPos;
00090   return *this;
00091 }
00092 
00093 inline CartesianPosition operator*(const CartesianPosition& pos, const float scale)
00094 {
00095   return CartesianPosition(pos[0]*scale,pos[1]*scale,pos[2]*scale,pos[3]*scale,pos[4]*scale,pos[5]*scale);
00096 }
00097 
00098 inline CartesianPosition& operator*=(CartesianPosition& pos, const float scale)
00099 {
00100   return (pos=pos*scale);
00101 }
00102 
00103 inline CartesianPosition operator+(const CartesianPosition& pos, const CartesianPosition& off)
00104 {
00105   return CartesianPosition(pos[0]+off[0],pos[1]+off[1],pos[2]+off[2],pos[3]+off[3],pos[4]+off[4],pos[5]+off[5]);
00106 }
00107 
00108 inline CartesianPosition& operator+=(CartesianPosition& pos, const CartesianPosition& off)
00109 {
00110   return (pos=pos+off);
00111 }
00112 
00113 inline CartesianPosition operator-(const CartesianPosition& pos, const CartesianPosition& off)
00114 {
00115   return CartesianPosition(pos[0]-off[0],pos[1]-off[1],pos[2]-off[2],pos[3]-off[3],pos[4]-off[4],pos[5]-off[5]);
00116 }
00117 
00118 inline CartesianPosition& operator-=(CartesianPosition& pos, const CartesianPosition& off)
00119 {
00120   return (pos=pos-off);
00121 }
00122 
00123 
00124 // 3D version of rectangle
00125 class Box
00126 {
00127 protected:
00128   // Center position
00129   CartesianPosition itsPos;
00130   // 3D dims
00131   CartesianPosition itsDims;
00132 public:
00133   Box(CartesianPosition pos, CartesianPosition dims) :
00134     itsPos(pos),
00135     itsDims(dims)
00136   {
00137   }
00138 
00139   bool dimContained(CartesianPosition pnt, size_t i)
00140   {
00141     ASSERT(i>=0 && i<=itsDims.size());
00142     // Check lower bound
00143     if(pnt[i] < itsPos[i]-itsDims[i]/2)
00144       return false;
00145     // Check upper bound
00146     if(pnt[i] > itsPos[i]+itsDims[i]/2)
00147       return false;
00148     return true;
00149   }
00150 
00151   bool contains(CartesianPosition pnt)
00152   {
00153     for(size_t i=0;i<itsDims.size();i++)
00154       { 
00155         if(!this->dimContained(pnt,i))
00156           return false;
00157       }
00158     return true;
00159   }
00160   float getVolume() { return itsDims[0]*itsDims[1]*itsDims[2]; }
00161   CartesianPosition getPosition() { return itsPos;}
00162   CartesianPosition getDimensions() { return itsDims;}
00163 };
00164 
00165 class Obj3DComponent : public nub::object
00166 {
00167 protected:
00168   // Type of object
00169   std::string itsType;
00170   rutz::shared_ptr<ViewPort3D> itsViewPort;
00171   CartesianPosition itsPos;
00172   PixRGB<byte> itsColor;
00173 
00174 public:
00175   virtual void draw() = 0;
00176   CartesianPosition getPosition() { return itsPos; }
00177   PixRGB<byte> getColor() { return itsColor; }
00178   void setPosition(CartesianPosition pos) { this->itsPos = pos; }
00179 
00180 protected:
00181   Obj3DComponent(std::string type,rutz::shared_ptr<ViewPort3D> vp,CartesianPosition pos,PixRGB<byte> color) :
00182     itsType(type),
00183     itsViewPort(vp),
00184     itsPos(pos),
00185     itsColor(color)
00186   {
00187 
00188   }
00189 };
00190 
00191 class Obj3DRectangle : public Obj3DComponent
00192 {
00193   float width;
00194   float height;
00195 
00196 public:
00197   Obj3DRectangle(rutz::shared_ptr<ViewPort3D> vp, CartesianPosition pos, PixRGB<byte> color, float width, float height) 
00198     : Obj3DComponent("Rectangle",vp,pos,color)
00199   {
00200     this->width = width;
00201     this->height = height;
00202   }
00203 
00204   virtual void draw()
00205   {
00206     Point3D<float> posPt(itsPos[0],itsPos[1],itsPos[2]);
00207     Point3D<float> rotPt(itsPos[3],itsPos[4],itsPos[5]);
00208     itsViewPort->drawRectangle(posPt,rotPt,width,height,itsColor);
00209   }
00210 };
00211 class Obj3DCircle : public Obj3DComponent
00212 {
00213   float radius;
00214 public:
00215   Obj3DCircle(rutz::shared_ptr<ViewPort3D> vp, CartesianPosition pos, PixRGB<byte> color, float radius) 
00216   : Obj3DComponent("Rectangle",vp,pos,color)
00217   {
00218     this->radius = radius;
00219   }
00220 
00221   virtual void draw()
00222   {
00223     Point3D<float> posPt(itsPos[0],itsPos[1],itsPos[2]);
00224     Point3D<float> rotPt(itsPos[3],itsPos[4],itsPos[5]);
00225     itsViewPort->drawCircle(posPt,rotPt,radius,itsColor);
00226   }
00227 };
00228 
00229 class Obj3DBox : public Obj3DComponent
00230 {
00231   Point3D<float> size;
00232 public:
00233   Obj3DBox(rutz::shared_ptr<ViewPort3D> vp, CartesianPosition pos, PixRGB<byte> color, Point3D<float> size) 
00234   : Obj3DComponent("Rectangle",vp,pos,color)
00235   {
00236     this->size = size;
00237   }
00238 
00239   virtual void draw()
00240   {
00241     Point3D<float> posPt(itsPos[0],itsPos[1],itsPos[2]);
00242     Point3D<float> rotPt(itsPos[3],itsPos[4],itsPos[5]);
00243     itsViewPort->drawBox(posPt,rotPt,size,itsColor);
00244   }
00245 };
00246 
00247 class Obj3DSphere : public Obj3DComponent
00248 {
00249   Point3D<float> size;
00250 public:
00251   Obj3DSphere(rutz::shared_ptr<ViewPort3D> vp, CartesianPosition pos, PixRGB<byte> color, Point3D<float> size) 
00252   : Obj3DComponent("Rectangle",vp,pos,color)
00253   {
00254     this->size = size;
00255   }
00256 
00257   virtual void draw()
00258   {
00259     Point3D<float> posPt(itsPos[0],itsPos[1],itsPos[2]);
00260     Point3D<float> rotPt(itsPos[3],itsPos[4],itsPos[5]);
00261     itsViewPort->drawSphere(posPt,rotPt,size,itsColor);
00262   }
00263 };
00264 
00265 class Obj3DCylinder : public Obj3DComponent
00266 {
00267   float radius;
00268   float length;
00269 public:
00270   Obj3DCylinder(rutz::shared_ptr<ViewPort3D> vp, CartesianPosition pos, PixRGB<byte> color, float radius, float length) 
00271   : Obj3DComponent("Rectangle",vp,pos,color)
00272   {
00273     this->radius = radius;
00274     this->length = length;
00275   }
00276 
00277   virtual void draw()
00278   {
00279     Point3D<float> posPt(itsPos[0],itsPos[1],itsPos[2]);
00280     Point3D<float> rotPt(itsPos[3],itsPos[4],itsPos[5]);
00281     itsViewPort->drawCylinder(posPt,rotPt,radius,length,itsColor);
00282   }
00283 };
00284 
00285 class Obj3DComposite : public Obj3DComponent
00286 {
00287   // Note order of members is important, as components are drawn in this order
00288   std::vector<rutz::shared_ptr<Obj3DComponent> > members;
00289   std::vector< CartesianPosition > offsets;
00290 public:
00291   Obj3DComposite(rutz::shared_ptr<ViewPort3D> vp, CartesianPosition pos, PixRGB<byte> color, 
00292                  std::vector<rutz::shared_ptr<Obj3DComponent> > members, std::vector< CartesianPosition > offsets)
00293   : Obj3DComponent("Rectangle",vp,pos,color)
00294   {
00295     this->members = members;
00296     this->offsets = offsets;
00297     ASSERT(offsets.size() == members.size());
00298   }
00299 
00300   virtual void draw()
00301   {
00302     for(size_t i=0;i<members.size();i++)
00303       {
00304         // Calculate transform between offset and global coordinate frame
00305         members[i]->setPosition(itsPos+offsets[i]);
00306         members[i]->draw();
00307       }
00308   }
00309 
00310 
00311 };
00312 
00313 // Subclasses should modify update function
00314 // Simple constant velocity trajectory generator, with bounds
00315 class ObjTrajectory
00316 {
00317 protected:
00318   Box itsBounds;
00319   CartesianPosition itsCurPos;
00320   CartesianPosition itsCurVel;
00321   //! Integration window 
00322   float itsIntegStep;
00323   //! Change in time per call (for constant velocity, iterStep==timeStep is ok, but with acceleration, should be integStep << timeStep)
00324   float itsTimeStep;
00325 public:
00326   ObjTrajectory(Box bounds, CartesianPosition initPos, CartesianPosition initVel, float integStep=0.01, float timeStep=0.1) :
00327     itsBounds(bounds),
00328     itsCurPos(initPos),
00329     itsCurVel(initVel)
00330   {
00331     itsIntegStep = integStep;
00332     itsTimeStep = timeStep;
00333     // Integration must be within or equal to the timestep
00334     ASSERT(itsIntegStep<=itsTimeStep);
00335     // The bounds must contain the initial position of the trajectory
00336     ASSERT(itsBounds.contains(itsCurPos));
00337   }
00338   
00339   void update()
00340   {
00341     for(int iter=0;iter*itsIntegStep<itsTimeStep;iter++)
00342       {
00343         CartesianPosition tmp = itsCurPos + itsCurVel*itsIntegStep;
00344         if(!itsBounds.contains(tmp))
00345           {
00346         for(size_t i=0;i<tmp.size();i++)
00347           {
00348             // Change velocity direction, based on any bound has been exceeded
00349             if(!itsBounds.dimContained(tmp,i))
00350               {
00351                 itsCurVel[i]=-itsCurVel[i];
00352               }
00353           }
00354           }
00355         else
00356           itsCurPos = tmp;
00357       }
00358   }
00359 
00360   CartesianPosition getPosition(){ return itsCurPos; }
00361 
00362 };
00363 
00364 
00365 rutz::shared_ptr<Obj3DComponent> initObject1(rutz::shared_ptr<ViewPort3D> vp)
00366 {
00367   CartesianPosition z(0,0,0,0,0,0);
00368   float basew=70,baseh=100;
00369   Obj3DRectangle *rbase = new Obj3DRectangle(vp,z,PixRGB<byte>(256,0,0),basew,baseh);
00370   float r1w=20,r1h=20;
00371   Obj3DRectangle *r1 = new Obj3DRectangle(vp,z,PixRGB<byte>(0,256,0),r1w,r1h);
00372   float c1r=8;
00373   Obj3DCircle *c1 = new Obj3DCircle(vp,z,PixRGB<byte>(0,0,256),c1r);
00374   Obj3DCircle *c2 = new Obj3DCircle(vp,z,PixRGB<byte>(0,0,256),c1r);
00375   std::vector<rutz::shared_ptr<Obj3DComponent> > members;
00376   members.push_back(rutz::shared_ptr<Obj3DComponent>(rbase));
00377   members.push_back(rutz::shared_ptr<Obj3DComponent>(r1));
00378   members.push_back(rutz::shared_ptr<Obj3DComponent>(c1));
00379   members.push_back(rutz::shared_ptr<Obj3DComponent>(c2));
00380   std::vector<CartesianPosition > offsets;
00381   offsets.push_back(CartesianPosition(0,0,-1,0,0,0));
00382   offsets.push_back(CartesianPosition(0,-30,0,0,0,0));
00383   offsets.push_back(CartesianPosition(20,30,0,0,0,0));
00384   offsets.push_back(CartesianPosition(-20,30,0,0,0,0));
00385   Obj3DComposite *comp = new Obj3DComposite(vp,z,PixRGB<byte>(0,0,0),members,offsets);
00386   return rutz::shared_ptr<Obj3DComponent>(comp);
00387 }
00388 
00389 int main(int argc, char *argv[]){
00390 
00391   ModelManager manager("Test Object World");
00392 
00393   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00394   manager.addSubComponent(ofs);
00395 
00396   // Parse command-line:
00397   if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00398   // let's get all our ModelComponent instances started:
00399   manager.start();
00400 
00401   //Normal operation
00402 
00403   rutz::shared_ptr<ViewPort3D> vp = rutz::shared_ptr<ViewPort3D>(new ViewPort3D(320,240, false, true, false));
00404   //ViewPort3D vp(320,240);
00405   vp->setCamera(Point3D<float>(0,0,350), Point3D<float>(0,0,0));
00406 
00407   CartesianPosition trajVel(2,2,0,0,0,0);
00408   rutz::shared_ptr<Obj3DComponent> obj1 = initObject1(vp);
00409   CartesianPosition boundSize(100,100,4,0,0,0);
00410   CartesianPosition z(0,0,0,0,0,0);
00411   Box bounds = Box(z,boundSize);
00412   ObjTrajectory traj1 = ObjTrajectory(bounds,z,trajVel);
00413   int rot = 0;
00414   while(1)
00415   {
00416     vp->initFrame();
00417     
00418     rot = ((rot +1)%360);
00419 
00420     std::vector<Point2D<float> > contour;
00421 
00422     Point3D<float> ctr = Point3D<float>(60,60,0);
00423     
00424     traj1.update();
00425     obj1->setPosition(traj1.getPosition());
00426     obj1->draw();
00427 
00428 
00429     Image<PixRGB<byte> > img = flipVertic(vp->getFrame());
00430     ofs->writeRGB(img, "ViewPort3D", FrameInfo("ViewPort3D", SRC_POS));
00431     usleep(10000);
00432   }
00433 
00434 
00435   exit(0);
00436 
00437 }
00438 
00439 
Generated on Sun May 8 08:40:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3