00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <assert.h>
00027 #include <Inventor/actions/SoRayPickAction.h>
00028 #include <Inventor/SoPickedPoint.h>
00029
00030 #include "scanSimulator.h"
00031 #include "graspitGUI.h"
00032 #include "ivmgr.h"
00033 #include "world.h"
00034 #include "matvec3D.h"
00035
00036 ScanSimulator::ScanSimulator()
00037 {
00038 setPosition( position(0,0,0), vec3(0,0,1), vec3(0,-1,0), STEREO_CAMERA );
00039 mHMin = -70; mHMax = 70; mHLines = 140;
00040 mVMin = -30; mVMax = 30; mVLines = 60;
00041 mType = SCANNER_COORDINATES;
00042 }
00043
00044 void ScanSimulator::setPosition(transf tr, AxesConvention convention)
00045 {
00046 mTran = tr;
00047 mTranInv = mTran.inverse();
00048 mPosition.set(tr.translation());
00049 switch (convention) {
00050 case STEREO_CAMERA:
00051 mDirection = tr.affine().row(2);
00052 mUp = -1.0 * tr.affine().row(1);
00053 mHorizDirection = mUp * mDirection;
00054 break;
00055 }
00056 }
00057
00058 void ScanSimulator::setPosition(position p, vec3 optical_axis, vec3 up_axis, AxesConvention convention)
00059 {
00060 mPosition = p; mDirection = normalise(optical_axis); mUp = normalise(up_axis);
00061 mHorizDirection = normalise(mUp * mDirection);
00062 mUp = mDirection * mHorizDirection;
00063 switch (convention) {
00064 case STEREO_CAMERA:
00065 mTran = transf( mat3(-1.0 * mHorizDirection, -1.0 * mUp, mDirection),
00066 vec3(mPosition.x(), mPosition.y(), mPosition.z() ) );
00067 mTranInv = mTran.inverse();
00068 break;
00069 }
00070 }
00071
00072 void ScanSimulator::scan(std::vector<position> *cloud, std::vector<RawScanPoint> *rawData)
00073 {
00074 float hfov = (mHMax - mHMin) * M_PI / 180.0;
00075 float vfov = (mVMax - mVMin) * M_PI / 180.0;
00076
00077 assert(hfov>=0 && vfov>=0);
00078 assert( mHLines > 0 && mVLines > 0);
00079
00080 float hstep = hfov / mHLines;
00081 float vstep = vfov / mVLines;
00082
00083 fprintf(stderr,"Vfov %f and vstep %f and lines %d\n",vfov,vstep,mVLines);
00084
00085 float hAngle;
00086 float vAngle = - vfov / 2.0;
00087
00088 vec3 rayDirection;
00089 position rayPoint;
00090 RawScanPoint rawPoint;
00091
00092 while( vAngle < vfov / 2.0) {
00093 hAngle = - hfov / 2.0;
00094 while (hAngle < hfov / 2.0) {
00095
00096 computeRayDirection( hAngle, vAngle, rayDirection);
00097 rawPoint.hAngle = hAngle; rawPoint.vAngle = vAngle;
00098 rawPoint.dx = rayDirection.x();
00099 rawPoint.dy = rayDirection.y();
00100 rawPoint.dz = rayDirection.z();
00101
00102 if ( shootRay( rayDirection, rayPoint ) ) {
00103 vec3 dist = rayPoint - mPosition;
00104 rawPoint.distance = dist.len();
00105
00106
00107 if (mType == SCANNER_COORDINATES) {
00108 rayPoint = rayPoint * mTranInv;
00109 }
00110 cloud->push_back(rayPoint);
00111
00112
00113 } else {
00114 rawPoint.distance = -1;
00115 }
00116
00117 if (rawData) {
00118 rawData->push_back( rawPoint );
00119 }
00120
00121 hAngle += hstep;
00122 }
00123 vAngle += vstep;
00124 fprintf(stderr,"Vangle: %f\n",vAngle);
00125 }
00126 }
00127
00128 void ScanSimulator::computeRayDirection(float hAngle, float vAngle, vec3 &rayDirection)
00129 {
00130 Quaternion r1(vAngle, mHorizDirection );
00131 Quaternion r2(hAngle, r1 * mUp);
00132 rayDirection = r2 * r1 * mDirection;
00133 }
00134
00135 bool ScanSimulator::shootRay(const vec3 &rayDirection, position &rayPoint)
00136 {
00137 SoRayPickAction action( graspItGUI->getIVmgr()->getViewer()->getViewportRegion() );
00138
00139 action.setRay( mPosition.toSbVec3f(), rayDirection.toSbVec3f(), 0.0, -1.0 );
00140 action.setPickAll(false);
00141
00142 action.apply( (SoNode*)graspItGUI->getIVmgr()->getWorld()->getIVRoot() );
00143
00144 SoPickedPoint *pp = action.getPickedPoint();
00145 if (!pp) return false;
00146
00147 rayPoint = position( pp->getPoint() );
00148 return true;
00149 }
00150