00001
00002 #include "main.h"
00003 #include "photo.h"
00004 #include "videoTexture.h"
00005
00006
00007
00008 Photo::Photo()
00009 : nxActor(NULL),
00010 node(NULL),
00011 texture(NULL),
00012 videoTexture(NULL),
00013 particelNode(NULL),
00014 particelEmitter(NULL),
00015 particelAffector(NULL),
00016 zoomStartPosition(0.0f),
00017 zoomDirection(0.0f),
00018 zoomTimeStart(0),
00019 zoomTimeForWay(0),
00020 zoomTimeStep(0),
00021 zoomState(PZS_ZOOMING_FINISHED)
00022 {
00023 logger->log( "Photo ctor()" );
00024 }
00025
00026
00027 Photo::~Photo()
00028 {
00029 if ( NULL != this->nxActor )
00030 {
00031
00032 nxScene->releaseActor( *this->nxActor );
00033 this->nxActor = NULL;
00034 }
00035 if ( NULL != this->texture )
00036 {
00037
00038 this->texture = NULL;
00039 }
00040 if ( NULL != this->particelEmitter )
00041 {
00042 this->particelEmitter->drop();
00043 this->particelEmitter = NULL;
00044 }
00045 if ( NULL != this->particelAffector )
00046 {
00047 this->particelAffector->drop();
00048 this->particelAffector = NULL;
00049 }
00050 if ( NULL != this->particelNode )
00051 {
00052 this->particelNode->removeAllAffectors();
00053 this->particelNode->remove();
00054 this->particelNode = NULL;
00055 }
00056 if ( NULL != this->node )
00057 {
00058 this->node->remove();
00059 this->node = NULL;
00060 }
00061 if ( NULL != this->videoTexture )
00062 {
00063 delete this->videoTexture;
00064 this->videoTexture = NULL;
00065 }
00066
00067 logger->log( "Photo dtor()" );
00068 }
00069
00070
00071
00072
00073
00074 ERR_TYPE Photo::update( u32 timeMS )
00075 {
00076 if ( (NULL == this->nxActor) || (NULL == this->node) )
00077 {
00078 return ERR_PHOTO_CREATEACTOR_FAILED;
00079 }
00080
00081
00082 if ( ! this->nxActor->isSleeping() )
00083 {
00084
00085
00086 NxMat34 pose = this->nxActor->getGlobalPose();
00087
00088 const NxVec3 pos = pose.t;
00089 const NxMat33 orient = pose.M;
00090 matrix4 irrMat;
00091 orient.getColumnMajorStride4( &irrMat[0] );
00092 pos.get( &irrMat[12] );
00093
00094 irrMat[3] = irrMat[7] = irrMat[11] = 0.0f;
00095 irrMat[15] = 1.0f;
00096
00097
00098 if ( NULL != this->node )
00099 {
00100 this->node->setPosition( irrMat.getTranslation() );
00101 this->node->setRotation( irrMat.getRotationDegrees() );
00102 }
00103 }
00104
00105
00106 if ( NULL != this->videoTexture )
00107 {
00108 this->videoTexture->update( timeMS );
00109 }
00110
00111
00112 if ( PZS_ZOOMING_FINISHED != this->zoomState )
00113 {
00114
00115 NxU32 t = ( timeMS - this->zoomTimeStart );
00116 NxVec3 pos = this->zoomStartPosition;
00117
00118 if ( t < this->zoomTimeForWay )
00119 {
00120
00121 pos += this->zoomDirection * ((NxF32) t) * this->zoomTimeStep;
00122 this->nxActor->moveGlobalPosition( pos );
00123 }
00124 else
00125 {
00126
00127
00128 if ( PZS_ZOOMING_TO_TABLE == this->zoomState )
00129 {
00130
00131 this->zoomState = PZS_ZOOMING_FINISHED;
00132
00133
00134 this->nxActor->clearActorFlag( NX_AF_DISABLE_COLLISION );
00135 this->nxActor->clearBodyFlag( NX_BF_KINEMATIC );
00136
00137
00138 this->nxActor->setAngularVelocity( NxVec3(0.0f) );
00139 this->nxActor->setLinearVelocity( NxVec3(0.0f) );
00140 this->nxActor->wakeUp();
00141 }
00142 }
00143 }
00144
00145 return ERR_OK;
00146 }
00147
00148
00149
00150 ERR_TYPE Photo::load( stringc meshFileName, stringc textureFileName, vector3df scale )
00151 {
00152 ERR_TYPE status = ERR_OK;
00153 stringc err("");
00154
00155 this->node = smgr->addAnimatedMeshSceneNode( smgr->getMesh( meshFileName.c_str() ) );
00156 if ( NULL == this->node )
00157 {
00158 return ERR_PHOTO_LOAD_FAILED;
00159 }
00160
00161
00162 status = this->createTextureWithBoarder( textureFileName );
00163 if ( (ERR_OK != status) || (NULL == this->texture) )
00164 {
00165 err = "Photo::load() cannot load ";
00166 err += textureFileName;
00167 err += " as bitmap. Trying to create as video.";
00168 logger->log( err.c_str() );
00169
00170
00171 this->videoTexture = new VideoTexture();
00172 status = this->videoTexture->openStream( textureFileName );
00173 if ( ERR_OK != status )
00174 {
00175 err = "Photo::load() cannot load ";
00176 err += textureFileName;
00177 err += " as video stream.";
00178 logger->log( err.c_str() );
00179
00180 delete this->videoTexture;
00181 this->videoTexture = NULL;
00182 this->node->remove();
00183 this->node = NULL;
00184 return ERR_PHOTO_LOAD_FAILED;
00185 }
00186
00187 this->texture = this->videoTexture->getTexture();
00188
00189
00190
00191 this->node->setMaterialFlag( EMF_LIGHTING, false );
00192
00193 }
00194 else
00195 {
00196
00197
00198 this->node->setMaterialFlag( EMF_LIGHTING, true );
00199 }
00200
00201
00202 this->node->setMaterialTexture( 0, this->texture );
00203
00204
00205
00206
00207 S3DVertex* vertices = (S3DVertex*) this->node->getMesh()->getMesh(0)->getMeshBuffer(0)->getVertices();
00208 u32 vertexCount = this->node->getMesh()->getMesh(0)->getMeshBuffer(0)->getVertexCount();
00209 for ( u32 i=0; i<vertexCount; i++ )
00210 {
00211
00212 if ( false == vertices[i].Normal.equals( vector3df(0.0f, 1.0f, 0.0f ) ) &&
00213 false == vertices[i].Normal.equals( vector3df(0.0f, -1.0f, 0.0f ) ) )
00214 {
00215
00216 vertices[i].TCoords.X = 0.0f;
00217 vertices[i].TCoords.Y = 0.0f;
00218 }
00219 }
00220
00221
00222 this->node->setScale( scale );
00223
00224
00225
00226 this->node->addShadowVolumeSceneNode();
00227
00228
00229 this->node->OnAnimate( 0 );
00230 aabbox3df boundingBox = this->node->getTransformedBoundingBox();
00231 vector3df sizeMax = boundingBox.MaxEdge;
00232 vector3df sizeMin = boundingBox.MinEdge;
00233 vector3df size = sizeMax + (-1.0f * sizeMin);
00234
00235 status = this->createNxActor( size );
00236 if ( ERR_OK != status )
00237 {
00238 this->node->remove();
00239 this->node = NULL;
00240 logger->log( "*** Error *** Photo::load() cannot create physX actor" );
00241 return status;
00242 }
00243
00244 return ERR_OK;
00245 }
00246
00247
00248
00249
00250 ERR_TYPE Photo::zoomStart( NxVec3 destinationPos, NxU32 timeForWayMS )
00251 {
00252 if ( (NULL == this->nxActor) || (NULL == this->node) )
00253 {
00254 return ERR_PHOTO_CREATEACTOR_FAILED;
00255 }
00256
00257
00258 this->zoomStartPosition = this->nxActor->getGlobalPosition();
00259 this->zoomTimeStart = timer->getRealTime();
00260 this->zoomTimeForWay = timeForWayMS;
00261 this->zoomDirection = destinationPos - this->zoomStartPosition;
00262 NxF32 zoomLength = this->zoomDirection.magnitude();
00263 this->zoomDirection.normalize();
00264 this->zoomTimeStep = zoomLength / timeForWayMS;
00265
00266
00267 this->nxActor->raiseActorFlag( NX_AF_DISABLE_COLLISION );
00268 this->nxActor->raiseBodyFlag( NX_BF_KINEMATIC );
00269
00270 this->zoomState = PZS_ZOOMING_TO_CAMERA;
00271
00272 return ERR_OK;
00273 }
00274
00275
00276
00277 ERR_TYPE Photo::zoomEnd()
00278 {
00279
00280 this->zoomStart( this->zoomStartPosition, this->zoomTimeForWay / 2 );
00281
00282 this->zoomState = PZS_ZOOMING_TO_TABLE;
00283
00284 return ERR_OK;
00285 }
00286
00287
00288
00289 ERR_TYPE Photo::particelStart( irr::core::stringc particelFileName )
00290 {
00291
00292 if ( NULL == this->particelNode )
00293 {
00294
00295 ITexture* particelTexture = driver->getTexture( particelFileName.c_str() );
00296 if ( NULL == particelTexture )
00297 {
00298 stringc err( "particelStart() cannot find texture: " );
00299 err += particelFileName;
00300 logger->log( err.c_str() );
00301 return ERR_PHOTO_CREATEPARTICEL_FAILED;
00302 }
00303
00304
00305 this->particelNode = smgr->addParticleSystemSceneNode();
00306 this->particelNode->setParticleSize( dimension2d<f32>(100.0f, 100.0f) );
00307 this->particelNode->setMaterialTexture( 0, particelTexture );
00308 this->particelNode->setMaterialFlag( EMF_LIGHTING, false );
00309 this->particelNode->setMaterialType( EMT_TRANSPARENT_ADD_COLOR );
00310
00311
00312 aabbox3d<f32> emittterBox(-8.0f, -1.0f, -8.0f, 8.0f, 1.0f, 8.0f);
00313 vector3df emitterDirection(0.0f, 0.02f, 0.0f);
00314 this->particelEmitter = this->particelNode->createBoxEmitter( emittterBox,
00315 emitterDirection,
00316 5,
00317 10,
00318 SColor(255,255,255,255),
00319 SColor(255,255,255,255),
00320 1100,
00321 2000 );
00322
00323
00324 this->particelAffector = this->particelNode->createFadeOutParticleAffector();
00325 this->particelNode->addAffector( this->particelAffector );
00326 }
00327
00328
00329
00330 vector3df particelNodeOffsetPos = this->node->getPosition();
00331 particelNodeOffsetPos.normalize();
00332 particelNodeOffsetPos.X *= 20.0f;
00333 particelNodeOffsetPos.Z *= 2.0f;
00334
00335 this->particelNode->setPosition( this->node->getPosition() + particelNodeOffsetPos );
00336 this->particelNode->setEmitter( this->particelEmitter );
00337
00338 return ERR_OK;
00339 }
00340
00341
00342
00343 ERR_TYPE Photo::particelEnd()
00344 {
00345 if ( NULL != this->particelNode )
00346 {
00347 this->particelNode->setEmitter( NULL );
00348 }
00349
00350 return ERR_OK;
00351 }
00352
00353
00354 ERR_TYPE Photo::applyForce( NxVec3 forceVector )
00355 {
00356 if ( NULL != this->nxActor )
00357 {
00358 this->nxActor->addForce( forceVector );
00359 }
00360 return ERR_OK;
00361 }
00362
00363 ERR_TYPE Photo::setPosition( NxVec3 newPosition )
00364 {
00365 if ( NULL != this->nxActor )
00366 {
00367 this->nxActor->setGlobalPosition( newPosition );
00368 }
00369 return ERR_OK;
00370 }
00371
00372 ERR_TYPE Photo::getPosition( NxVec3* outPosition )
00373 {
00374 if ( NULL != this->nxActor )
00375 {
00376 *outPosition = this->nxActor->getGlobalPosition();
00377 }
00378 return ERR_OK;
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388 ERR_TYPE Photo::createNxActor( vector3df size )
00389 {
00390
00391 NxReal irrToPhysxScaler = 0.5f;
00392 NxVec3 boxDim( size.X * irrToPhysxScaler, size.Y * irrToPhysxScaler, size.Z * irrToPhysxScaler );
00393
00394
00395 NxActorDesc actorDesc;
00396 NxBodyDesc bodyDesc;
00397
00398
00399 NxBoxShapeDesc boxDesc;
00400 boxDesc.dimensions.set( boxDim );
00401
00402 actorDesc.shapes.pushBack( &boxDesc );
00403
00404 actorDesc.body = &bodyDesc;
00405 actorDesc.density = 20.0f;
00406
00407 actorDesc.userData = (void*) this;
00408
00409 this->nxActor = nxScene->createActor( actorDesc );
00410 if ( NULL == this->nxActor )
00411 {
00412 return ERR_TABLE_CREATEACTOR_FAILED;
00413 }
00414
00415 this->nxActor->setName( "Photo" );
00416
00417 return ERR_OK;
00418 }
00419
00420
00421
00422
00423
00424
00425 ERR_TYPE Photo::createTextureWithBoarder( stringc imageFileName )
00426 {
00427 IImage* image = driver->createImageFromFile( imageFileName.c_str() );
00428 if ( NULL == image )
00429 {
00430 return ERR_PHOTO_LOAD_FAILED;
00431 }
00432
00433
00434 dimension2d<s32> imageSize( image->getDimension() );
00435
00436
00437 dimension2d<s32> textureSize( imageSize );
00438
00439 s32 borderX = imageSize.Width / 8;
00440 s32 borderY = imageSize.Height / 8;
00441
00442 textureSize.Width += borderX;
00443 textureSize.Height += borderY;
00444
00445
00446 if ( false == driver->queryFeature(EVDF_TEXTURE_NPOT) )
00447 {
00448
00449 s32 optimalTextureWidth = 0x01;
00450 while ( optimalTextureWidth < textureSize.Width )
00451 {
00452 optimalTextureWidth <<= 1;
00453 }
00454 textureSize.Width = optimalTextureWidth;
00455
00456
00457 s32 optimalTextureHeight = 0x01;
00458 while ( optimalTextureHeight < textureSize.Height )
00459 {
00460 optimalTextureHeight <<= 1;
00461 }
00462 textureSize.Height = optimalTextureHeight;
00463
00464
00465 dimension2d<s32> scaledImageSize( textureSize.Width - borderX, textureSize.Height - borderY );
00466 u8* scaledData = (u8*) malloc( scaledImageSize.Width * scaledImageSize.Height * 4 );
00467 if ( NULL != scaledData )
00468 {
00469 IImage* scaledImage = driver->createImageFromData( ECF_A8R8G8B8, scaledImageSize, scaledData );
00470 image->copyToScaling( scaledImage );
00471 free( scaledData );
00472
00473 image->drop();
00474
00475 image = scaledImage;
00476 imageSize = scaledImageSize;
00477 }
00478 else
00479 {
00480
00481 borderX = textureSize.Width - imageSize.Width;
00482 borderY = textureSize.Height - imageSize.Height;
00483 }
00484 }
00485
00486
00487 this->texture = driver->addTexture( textureSize, imageFileName.c_str(), ECF_A8R8G8B8 );
00488 if ( NULL == this->texture )
00489 {
00490 image->drop();
00491 return ERR_PHOTO_LOAD_FAILED;
00492 }
00493
00494
00495 ECOLOR_FORMAT colorFormat = this->texture->getColorFormat();
00496 if ( colorFormat != ECF_A8R8G8B8 )
00497 {
00498 logger->log( "createTextureWithBoarder() Warning, texture color format mismatch" );
00499 image->drop();
00500 return ERR_PHOTO_LOAD_FAILED;
00501 }
00502
00503
00504 u8* imageData = (u8*) image->lock();
00505 if ( NULL == imageData )
00506 {
00507 logger->log( "createTextureWithBoarder() cannot access image data" );
00508 image->drop();
00509 return ERR_PHOTO_LOAD_FAILED;
00510 }
00511
00512
00513 u8* textureData = (u8*) this->texture->lock();
00514 if ( NULL == textureData )
00515 {
00516 logger->log( "createTextureWithBoarder() cannot access texture data" );
00517 image->drop();
00518 return ERR_PHOTO_LOAD_FAILED;
00519 }
00520
00521
00522 memset( textureData, 0xFF, textureSize.Height * textureSize.Width * 4 );
00523
00524
00525
00526 u32 pitch = this->texture->getPitch();
00527 for (s32 y=0; y<imageSize.Height; y++)
00528 {
00529 for (s32 x=0; x<imageSize.Width; x++)
00530 {
00531 s32 color = image->getPixel( x, y ).color;
00532 u32* dest = (u32*) ((u8*) textureData + ( (y+borderY/2) * pitch ) + ( (x+borderX/2) << 2 ));
00533 *dest = color;
00534 }
00535 }
00536
00537 this->texture->unlock();
00538 image->unlock();
00539
00540
00541 image->drop();
00542
00543 return ERR_OK;
00544 }