00001
00002 #include "main.h"
00003 #include "mouse.h"
00004
00005
00006
00007
00008 Mouse::Mouse( NxReal size, NxReal mouseOperatingHight, NxReal pickedActorLiftUp )
00009 : mouseActor(NULL),
00010 joint(NULL),
00011 mouseOperatingHight(mouseOperatingHight),
00012 pickedActorLiftUp(pickedActorLiftUp)
00013 {
00014 logger->log( "Mouse ctor()" );
00015 this->createMouseActor( size );
00016 }
00017
00018
00019
00020 Mouse::~Mouse()
00021 {
00022
00023 if ( NULL != this->joint )
00024 {
00025 nxScene->releaseJoint( *this->joint );
00026 this->joint = NULL;
00027 }
00028 if ( NULL != this->mouseActor )
00029 {
00030 nxScene->releaseActor( *this->mouseActor );
00031 this->mouseActor = NULL;
00032 }
00033
00034 logger->log( "Mouse dtor()" );
00035 }
00036
00037
00038
00039 ERR_TYPE Mouse::moveTo( NxU32 x, NxU32 y )
00040 {
00041 if ( NULL != this->mouseActor )
00042 {
00043
00044
00045 if ( NULL != this->joint )
00046 {
00047 NxActor* tempActor;
00048 NxActor* tempMouse;
00049 this->joint->getActors( &tempActor, &tempMouse );
00050 tempActor->wakeUp();
00051 }
00052
00053 line3df line = getCameraToTableRay( x, y );
00054
00055 NxVec3 intersection = getRayIntersectionWithTable( line );
00056
00057 NxVec3 newPos( intersection.x, this->mouseOperatingHight, intersection.z );
00058 this->mouseActor->setGlobalPosition( newPos );
00059 }
00060
00061 return ERR_OK;
00062 }
00063
00064
00065
00066 ERR_TYPE Mouse::pickActorElasticStrap( NxActor* actor )
00067 {
00068 if ( NULL != actor )
00069 {
00070
00071 NxVec3 actorPos( actor->getGlobalPosition() );
00072 actorPos.y += this->pickedActorLiftUp;
00073 actor->setGlobalPosition( actorPos );
00074
00075
00076 NxVec3 jointPos( this->mouseActor->getGlobalPosition() );
00077 jointPos.y -= 1.0f;
00078
00079
00080 this->createDistanceJoint( actor, jointPos );
00081 }
00082
00083 return ERR_OK;
00084 }
00085
00086
00087
00088 ERR_TYPE Mouse::pickActorFixed( NxActor* actor )
00089 {
00090 if ( NULL != actor )
00091 {
00092
00093 NxVec3 actorPos( actor->getGlobalPosition() );
00094 actorPos.y += this->pickedActorLiftUp;
00095 actor->setGlobalPosition( actorPos );
00096 actor->raiseBodyFlag( NX_BF_FROZEN_ROT );
00097
00098
00099 NxVec3 jointPos( this->mouseActor->getGlobalPosition() );
00100 jointPos.y -= 1.0f;
00101
00102
00103 this->createSphericalJoint( actor, jointPos );
00104 }
00105
00106 return ERR_OK;
00107 }
00108
00109
00110
00111 ERR_TYPE Mouse::dropActor()
00112 {
00113
00114 if ( NULL != this->joint )
00115 {
00116
00117 NxActor* tempActor;
00118 NxActor* tempMouse;
00119 this->joint->getActors( &tempActor, &tempMouse );
00120 tempActor->clearBodyFlag( NX_BF_FROZEN_ROT );
00121
00122 nxScene->releaseJoint( *this->joint );
00123 this->joint = NULL;
00124
00125 }
00126
00127 return ERR_OK;
00128 }
00129
00130
00131
00132
00133
00134 NxActor* Mouse::actorHit( NxU32 inX, NxU32 inY )
00135 {
00136
00137 line3df line = this->getCameraToTableRay( inX, inY );
00138
00139
00140 NxVec3 rayStart( line.start.X, line.start.Y, line.start.Z );
00141 NxVec3 rayEnd( line.end.X, line.end.Y, line.end.Z );
00142 NxVec3 rayDir = rayEnd - rayStart;
00143 rayDir.normalize();
00144
00145 NxRay theRay( rayStart, rayDir );
00146
00147
00148 NxRaycastHit hit;
00149 NxShape* thePickedPhotoShape = NULL;
00150 thePickedPhotoShape = nxScene->raycastClosestShape( theRay, NX_ALL_SHAPES, hit );
00151
00152 if ( NULL != thePickedPhotoShape )
00153 {
00154 return &thePickedPhotoShape->getActor();
00155 }
00156
00157 return NULL;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 ERR_TYPE Mouse::createMouseActor( NxReal size )
00169 {
00170
00171 NxVec3 boxDim( size, size, size );
00172
00173
00174 NxActorDesc actorDesc;
00175 NxBodyDesc bodyDesc;
00176
00177
00178 NxBoxShapeDesc boxDesc;
00179 boxDesc.dimensions.set( boxDim );
00180
00181
00182
00183 boxDesc.shapeFlags |= NX_SF_DISABLE_RAYCASTING;
00184
00185
00186 boxDesc.localPose.t = NxVec3( 0.0f, boxDim.y, 0.0f );
00187
00188 actorDesc.shapes.pushBack( &boxDesc );
00189
00190 actorDesc.body = &bodyDesc;
00191 actorDesc.density = 10000.0f;
00192
00193 this->mouseActor = nxScene->createActor( actorDesc );
00194 if ( NULL == this->mouseActor )
00195 {
00196 logger->log( "createMouseActor() cannot create NxActor" );
00197 return ERR_MOUSE_CREATE_MOUSE_FAILED;
00198 }
00199
00200 this->mouseActor->setName( "MousePointer" );
00201
00202 this->mouseActor->raiseBodyFlag( NX_BF_KINEMATIC );
00203
00204 this->mouseActor->raiseActorFlag( NX_AF_DISABLE_COLLISION );
00205
00206 return ERR_OK;
00207 }
00208
00209
00210
00211 ERR_TYPE Mouse::createDistanceJoint( NxActor* actor, NxVec3 position )
00212 {
00213 NxDistanceJointDesc jointDesc;
00214 jointDesc.name = "MousePick";
00215 jointDesc.actor[0] = actor;
00216 jointDesc.actor[1] = this->mouseActor;
00217
00218 jointDesc.maxDistance = 2.0f;
00219
00220 jointDesc.minDistance = 1.0f;
00221
00222 jointDesc.flags = ( NX_DJF_MIN_DISTANCE_ENABLED | NX_DJF_MAX_DISTANCE_ENABLED );
00223
00224
00225 NxMat34 photoInverse;
00226 actor->getGlobalPose().getInverse( photoInverse );
00227 NxVec3 photoLocalPos;
00228 photoInverse.multiply( this->mouseActor->getGlobalPosition(), photoLocalPos );
00229 photoLocalPos.y = 0.0f;
00230
00231
00232 jointDesc.localAnchor[0] = photoLocalPos;
00233 jointDesc.localAnchor[1] = NxVec3(0.0f, 0.0f, 0.0f);
00234
00235
00236 NxSpringDesc spring;
00237 spring.spring = 90000.0;
00238 spring.damper = 80000.0f;
00239 jointDesc.spring = spring;
00240 jointDesc.flags |= NX_DJF_SPRING_ENABLED;
00241
00242 jointDesc.jointFlags |= NX_JF_VISUALIZATION;
00243
00244
00245 if ( jointDesc.isValid() )
00246 {
00247 this->joint = nxScene->createJoint( jointDesc );
00248 if ( NULL != joint )
00249 {
00250
00251 }
00252 else
00253 {
00254 logger->log( "Cannot create joint to pick photo" );
00255 return ERR_MOUSE_CREATE_JOINT_FAILED;
00256 }
00257 }
00258 else
00259 {
00260 logger->log( "Cannot create joint to pick photo" );
00261 return ERR_MOUSE_CREATE_JOINT_FAILED;
00262 }
00263
00264 return ERR_OK;
00265 }
00266
00267
00268
00269 ERR_TYPE Mouse::createSphericalJoint( NxActor* actor, NxVec3 position )
00270 {
00271 NxSphericalJointDesc jointDesc;
00272 jointDesc.name = "MousePick";
00273 jointDesc.actor[0] = actor;
00274 jointDesc.actor[1] = this->mouseActor;
00275 jointDesc.jointFlags |= NX_JF_VISUALIZATION;
00276 jointDesc.setGlobalAnchor( position );
00277 jointDesc.setGlobalAxis( NxVec3(0.0f, 1.0f, 0.0f) );
00278
00279
00280 if ( jointDesc.isValid() )
00281 {
00282 this->joint = nxScene->createJoint( jointDesc );
00283 if ( NULL != joint )
00284 {
00285
00286 }
00287 else
00288 {
00289 logger->log( "Cannot create joint to pick photo" );
00290 return ERR_MOUSE_CREATE_JOINT_FAILED;
00291 }
00292 }
00293 else
00294 {
00295 logger->log( "Cannot create joint to pick photo" );
00296 return ERR_MOUSE_CREATE_JOINT_FAILED;
00297 }
00298
00299 return ERR_OK;
00300 }
00301
00302
00303
00304 NxVec3 Mouse::getRayIntersectionWithTable( line3df line )
00305 {
00306 f32 tableSurfaceYPos = 10.0f;
00307
00308
00309 plane3df tempTable = plane3df( vector3df( -100.0f, tableSurfaceYPos, 100.0f ),
00310 vector3df( 100.0f, tableSurfaceYPos, 100.0f ),
00311 vector3df( 0.0f, tableSurfaceYPos, -100.0f ) );
00312
00313
00314 vector3df theIntersection;
00315 tempTable.getIntersectionWithLimitedLine( line.start, line.end, theIntersection );
00316
00317
00318 NxVec3 result( theIntersection.X, theIntersection.Y, theIntersection.Z );
00319
00320 return result;
00321 }
00322
00323
00324
00325 line3df Mouse::getCameraToTableRay( s32 mouseX, s32 mouseY )
00326 {
00327 line3df line( 0, 0, 0, 0, 0, 0 );
00328
00329 ICameraSceneNode* aCam = smgr->getActiveCamera();
00330
00331 const SViewFrustum* f = aCam->getViewFrustum();
00332
00333 vector3df farLeftUp = f->getFarLeftUp();
00334 vector3df lefttoright = f->getFarRightUp() - farLeftUp;
00335 vector3df uptodown = f->getFarLeftDown() - farLeftUp;
00336
00337 rect<s32> viewPort = driver->getViewPort();
00338 dimension2d<s32> screenSize(viewPort.getWidth(), viewPort.getHeight());
00339
00340 f32 dx = mouseX / (f32)screenSize.Width;
00341 f32 dy = mouseY / (f32)screenSize.Height;
00342
00343 line.start = f->cameraPosition;
00344 line.end = farLeftUp + (lefttoright * dx) + (uptodown * dy);
00345
00346 return line;
00347 }