guiObjectView.cpp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "T3D/guiObjectView.h"
  23. #include "renderInstance/renderPassManager.h"
  24. #include "lighting/lightManager.h"
  25. #include "lighting/lightInfo.h"
  26. #include "core/resourceManager.h"
  27. #include "scene/sceneManager.h"
  28. #include "scene/sceneRenderState.h"
  29. #include "console/consoleTypes.h"
  30. #include "math/mathTypes.h"
  31. #include "gfx/gfxTransformSaver.h"
  32. #include "console/engineAPI.h"
  33. IMPLEMENT_CONOBJECT( GuiObjectView );
  34. ConsoleDocClass( GuiObjectView,
  35. "@brief GUI control which displays a 3D model.\n\n"
  36. "Model displayed in the control can have other objects mounted onto it, and the light settings can be adjusted.\n\n"
  37. "@tsexample\n"
  38. " new GuiObjectView(ObjectPreview)\n"
  39. " {\n"
  40. " shapeFile = \"art/shapes/items/kit/healthkit.dts\";\n"
  41. " mountedNode = \"mount0\";\n"
  42. " lightColor = \"1 1 1 1\";\n"
  43. " lightAmbient = \"0.5 0.5 0.5 1\";\n"
  44. " lightDirection = \"0 0.707 -0.707\";\n"
  45. " orbitDiststance = \"2\";\n"
  46. " minOrbitDiststance = \"0.917688\";\n"
  47. " maxOrbitDiststance = \"5\";\n"
  48. " cameraSpeed = \"0.01\";\n"
  49. " cameraZRot = \"0\";\n"
  50. " forceFOV = \"0\";\n"
  51. " reflectPriority = \"0\";\n"
  52. " };\n"
  53. "@endtsexample\n\n"
  54. "@see GuiControl\n\n"
  55. "@ingroup Gui3D\n"
  56. );
  57. IMPLEMENT_CALLBACK( GuiObjectView, onMouseEnter, void, (),(),
  58. "@brief Called whenever the mouse enters the control.\n\n"
  59. "@tsexample\n"
  60. "// The mouse has entered the control, causing the callback to occur\n"
  61. "GuiObjectView::onMouseEnter(%this)\n"
  62. " {\n"
  63. " // Code to run when the mouse enters this control\n"
  64. " }\n"
  65. "@endtsexample\n\n"
  66. "@see GuiControl\n\n"
  67. );
  68. IMPLEMENT_CALLBACK( GuiObjectView, onMouseLeave, void, (),(),
  69. "@brief Called whenever the mouse leaves the control.\n\n"
  70. "@tsexample\n"
  71. "// The mouse has left the control, causing the callback to occur\n"
  72. "GuiObjectView::onMouseLeave(%this)\n"
  73. " {\n"
  74. " // Code to run when the mouse leaves this control\n"
  75. " }\n"
  76. "@endtsexample\n\n"
  77. "@see GuiControl\n\n"
  78. );
  79. //------------------------------------------------------------------------------
  80. GuiObjectView::GuiObjectView()
  81. : mMouseState( None ),
  82. mLastMousePoint( 0, 0 ),
  83. mModel( NULL ),
  84. mMaxOrbitDist( 5.0f ),
  85. mMinOrbitDist( 0.0f ),
  86. mCameraRotation( 0.0f, 0.0f, 0.0f ),
  87. mOrbitDist( 5.0f ),
  88. mCameraSpeed( 0.01f ),
  89. mMountNode( -1 ),
  90. mMountNodeName( "mount0" ),
  91. mMountedModel( NULL ),
  92. mAnimationSeq( -1 ),
  93. mRunThread( NULL ),
  94. mLastRenderTime( 0 ),
  95. mLight( NULL ),
  96. mLightColor( 1.0f, 1.0f, 1.0f ),
  97. mLightAmbient( 0.5f, 0.5f, 0.5f ),
  98. mLightDirection( 0.f, 0.707f, -0.707f )
  99. {
  100. mCameraMatrix.identity();
  101. mCameraRot.set( 0.0f, 0.0f, 3.9f );
  102. mCameraPos.set( 0.0f, 0.0f, 0.0f );
  103. mCameraMatrix.setColumn( 3, mCameraPos );
  104. mOrbitPos.set( 0.0f, 0.0f, 0.0f );
  105. // By default don't do dynamic reflection
  106. // updates for this viewport.
  107. mReflectPriority = 0.0f;
  108. }
  109. //------------------------------------------------------------------------------
  110. GuiObjectView::~GuiObjectView()
  111. {
  112. if( mModel )
  113. SAFE_DELETE( mModel );
  114. if( mMountedModel )
  115. SAFE_DELETE( mMountedModel );
  116. if( mLight )
  117. SAFE_DELETE( mLight );
  118. }
  119. //------------------------------------------------------------------------------
  120. void GuiObjectView::initPersistFields()
  121. {
  122. docsURL;
  123. addGroup( "Model" );
  124. addField( "shapeFile", TypeStringFilename, Offset( mModelName, GuiObjectView ),
  125. "The object model shape file to show in the view." );
  126. addField( "skin", TypeRealString, Offset( mSkinName, GuiObjectView ),
  127. "The skin to use on the object model." );
  128. endGroup( "Model" );
  129. addGroup( "Animation" );
  130. addField( "animSequence", TypeRealString, Offset( mAnimationSeqName, GuiObjectView ),
  131. "The animation sequence to play on the model." );
  132. endGroup( "Animation" );
  133. addGroup( "Mounting" );
  134. addField( "mountedShapeFile", TypeStringFilename, Offset( mMountedModelName, GuiObjectView ),
  135. "Optional shape file to mount on the primary model (e.g. weapon)." );
  136. addField( "mountedSkin", TypeRealString, Offset( mMountSkinName, GuiObjectView ),
  137. "Skin name used on mounted shape file." );
  138. addField( "mountedNode", TypeRealString, Offset( mMountNodeName, GuiObjectView ),
  139. "Name of node on primary model to which to mount the secondary shape." );
  140. endGroup( "Mounting" );
  141. addGroup( "Lighting" );
  142. addField( "lightColor", TypeColorF, Offset( mLightColor, GuiObjectView ),
  143. "Diffuse color of the sunlight used to render the model." );
  144. addField( "lightAmbient", TypeColorF, Offset( mLightAmbient, GuiObjectView ),
  145. "Ambient color of the sunlight used to render the model." );
  146. addField( "lightDirection", TypePoint3F, Offset( mLightDirection, GuiObjectView ),
  147. "Direction from which the model is illuminated." );
  148. endGroup( "Lighting" );
  149. addGroup( "Camera" );
  150. addField( "orbitDiststance", TypeF32, Offset( mOrbitDist, GuiObjectView ),
  151. "Distance from which to render the model." );
  152. addField( "minOrbitDiststance", TypeF32, Offset( mMinOrbitDist, GuiObjectView ),
  153. "Maxiumum distance to which the camera can be zoomed out." );
  154. addField( "maxOrbitDiststance", TypeF32, Offset( mMaxOrbitDist, GuiObjectView ),
  155. "Minimum distance below which the camera will not zoom in further." );
  156. addField( "cameraSpeed", TypeF32, Offset( mCameraSpeed, GuiObjectView ),
  157. "Multiplier for mouse camera operations." );
  158. addField( "cameraRotation", TypePoint3F, Offset( mCameraRotation, GuiObjectView ),
  159. "Set the camera rotation." );
  160. endGroup( "Camera" );
  161. Parent::initPersistFields();
  162. }
  163. //------------------------------------------------------------------------------
  164. void GuiObjectView::onStaticModified( StringTableEntry slotName, const char* newValue )
  165. {
  166. Parent::onStaticModified( slotName, newValue );
  167. static StringTableEntry sShapeFile = StringTable->insert( "shapeFile" );
  168. static StringTableEntry sSkin = StringTable->insert( "skin" );
  169. static StringTableEntry sMountedShapeFile = StringTable->insert( "mountedShapeFile" );
  170. static StringTableEntry sMountedSkin = StringTable->insert( "mountedSkin" );
  171. static StringTableEntry sMountedNode = StringTable->insert( "mountedNode" );
  172. static StringTableEntry sLightColor = StringTable->insert( "lightColor" );
  173. static StringTableEntry sLightAmbient = StringTable->insert( "lightAmbient" );
  174. static StringTableEntry sLightDirection = StringTable->insert( "lightDirection" );
  175. static StringTableEntry sOrbitDistance = StringTable->insert( "orbitDistance" );
  176. static StringTableEntry sMinOrbitDistance = StringTable->insert( "minOrbitDistance" );
  177. static StringTableEntry sMaxOrbitDistance = StringTable->insert( "maxOrbitDistance" );
  178. static StringTableEntry sCameraRotation = StringTable->insert( "cameraRotation" );
  179. static StringTableEntry sAnimSequence = StringTable->insert( "animSequence" );
  180. if( slotName == sShapeFile )
  181. setObjectModel( String( mModelName ) );
  182. else if( slotName == sSkin )
  183. setSkin( String( mSkinName ) );
  184. else if( slotName == sMountedShapeFile )
  185. setMountedObject( String( mMountedModelName ) );
  186. else if( slotName == sMountedSkin )
  187. setMountSkin( String( mMountSkinName ) );
  188. else if( slotName == sMountedNode )
  189. setMountNode( String( mMountNodeName ) );
  190. else if( slotName == sLightColor )
  191. setLightColor( mLightColor );
  192. else if( slotName == sLightAmbient )
  193. setLightAmbient( mLightAmbient );
  194. else if( slotName == sLightDirection )
  195. setLightDirection( mLightDirection );
  196. else if( slotName == sOrbitDistance || slotName == sMinOrbitDistance || slotName == sMaxOrbitDistance )
  197. setOrbitDistance( mOrbitDist );
  198. else if( slotName == sCameraRotation )
  199. setCameraRotation( mCameraRotation );
  200. else if( slotName == sAnimSequence )
  201. setObjectAnimation( String( mAnimationSeqName ) );
  202. }
  203. //------------------------------------------------------------------------------
  204. bool GuiObjectView::onWake()
  205. {
  206. if( !Parent::onWake() )
  207. return false;
  208. if( !mLight )
  209. {
  210. mLight = LIGHTMGR->createLightInfo();
  211. mLight->setColor( mLightColor );
  212. mLight->setAmbient( mLightAmbient );
  213. mLight->setDirection( mLightDirection );
  214. }
  215. return true;
  216. }
  217. //------------------------------------------------------------------------------
  218. void GuiObjectView::onMouseDown( const GuiEvent &event )
  219. {
  220. if( !mActive || !mVisible || !mAwake )
  221. return;
  222. mMouseState = Rotating;
  223. mLastMousePoint = event.mousePoint;
  224. mouseLock();
  225. }
  226. //------------------------------------------------------------------------------
  227. void GuiObjectView::onMouseUp( const GuiEvent &event )
  228. {
  229. mouseUnlock();
  230. mMouseState = None;
  231. }
  232. //------------------------------------------------------------------------------
  233. void GuiObjectView::onMouseDragged( const GuiEvent &event )
  234. {
  235. if( mMouseState != Rotating )
  236. return;
  237. Point2I delta = event.mousePoint - mLastMousePoint;
  238. mLastMousePoint = event.mousePoint;
  239. mCameraRot.x += ( delta.y * mCameraSpeed );
  240. mCameraRot.z += ( delta.x * mCameraSpeed );
  241. }
  242. //------------------------------------------------------------------------------
  243. void GuiObjectView::onRightMouseDown( const GuiEvent &event )
  244. {
  245. mMouseState = Zooming;
  246. mLastMousePoint = event.mousePoint;
  247. mouseLock();
  248. }
  249. //------------------------------------------------------------------------------
  250. void GuiObjectView::onRightMouseUp( const GuiEvent &event )
  251. {
  252. mouseUnlock();
  253. mMouseState = None;
  254. }
  255. //------------------------------------------------------------------------------
  256. void GuiObjectView::onRightMouseDragged( const GuiEvent &event )
  257. {
  258. if( mMouseState != Zooming )
  259. return;
  260. S32 delta = event.mousePoint.y - mLastMousePoint.y;
  261. mLastMousePoint = event.mousePoint;
  262. mOrbitDist += ( delta * mCameraSpeed );
  263. }
  264. //------------------------------------------------------------------------------
  265. void GuiObjectView::setObjectAnimation( S32 index )
  266. {
  267. mAnimationSeq = index;
  268. mAnimationSeqName = String();
  269. if( mModel )
  270. _initAnimation();
  271. }
  272. //------------------------------------------------------------------------------
  273. void GuiObjectView::setObjectAnimation( const String& sequenceName )
  274. {
  275. mAnimationSeq = -1;
  276. mAnimationSeqName = sequenceName;
  277. if( mModel )
  278. _initAnimation();
  279. }
  280. //------------------------------------------------------------------------------
  281. void GuiObjectView::setObjectModel( const String& modelName )
  282. {
  283. SAFE_DELETE( mModel );
  284. mRunThread = 0;
  285. mModelName = String::EmptyString;
  286. // Load the shape.
  287. Resource< TSShape > model = ResourceManager::get().load( modelName );
  288. if( !model )
  289. {
  290. Con::warnf( "GuiObjectView::setObjectModel - Failed to load model '%s'", modelName.c_str() );
  291. return;
  292. }
  293. // Instantiate it.
  294. mModel = new TSShapeInstance( model, true );
  295. mModelName = modelName;
  296. if( !mSkinName.isEmpty() )
  297. mModel->reSkin( mSkinName );
  298. // Initialize camera values.
  299. mOrbitPos = mModel->getShape()->center;
  300. mMinOrbitDist = mModel->getShape()->mRadius;
  301. // Initialize animation.
  302. _initAnimation();
  303. _initMount();
  304. }
  305. //------------------------------------------------------------------------------
  306. void GuiObjectView::setSkin( const String& name )
  307. {
  308. if( mModel )
  309. mModel->reSkin( name, mSkinName );
  310. mSkinName = name;
  311. }
  312. //------------------------------------------------------------------------------
  313. void GuiObjectView::setMountSkin( const String& name )
  314. {
  315. if( mMountedModel )
  316. mMountedModel->reSkin( name, mMountSkinName );
  317. mMountSkinName = name;
  318. }
  319. //------------------------------------------------------------------------------
  320. void GuiObjectView::setMountNode( S32 index )
  321. {
  322. setMountNode( String::ToString( "mount%i", index ) );
  323. }
  324. //------------------------------------------------------------------------------
  325. void GuiObjectView::setMountNode( const String& name )
  326. {
  327. mMountNodeName = name;
  328. if( mModel )
  329. _initMount();
  330. }
  331. //------------------------------------------------------------------------------
  332. void GuiObjectView::setMountedObject( const String& modelName )
  333. {
  334. SAFE_DELETE( mMountedModel );
  335. mMountedModelName = String::EmptyString;
  336. // Load the model.
  337. Resource< TSShape > model = ResourceManager::get().load( modelName );
  338. if( !model )
  339. {
  340. Con::warnf( "GuiObjectView::setMountedObject - Failed to load object model '%s'",
  341. modelName.c_str() );
  342. return;
  343. }
  344. mMountedModel = new TSShapeInstance( model, true );
  345. mMountedModelName = modelName;
  346. if( !mMountSkinName.isEmpty() )
  347. mMountedModel->reSkin( mMountSkinName );
  348. if( mModel )
  349. _initMount();
  350. }
  351. //------------------------------------------------------------------------------
  352. bool GuiObjectView::processCameraQuery( CameraQuery* query )
  353. {
  354. // Adjust the camera so that we are still facing the model.
  355. Point3F vec;
  356. MatrixF xRot, zRot;
  357. xRot.set( EulerF( mCameraRot.x, 0.0f, 0.0f ) );
  358. zRot.set( EulerF( 0.0f, 0.0f, mCameraRot.z ) );
  359. mCameraMatrix.mul( zRot, xRot );
  360. mCameraMatrix.getColumn( 1, &vec );
  361. vec *= mOrbitDist;
  362. mCameraPos = mOrbitPos - vec;
  363. query->farPlane = 2100.0f;
  364. query->nearPlane = query->farPlane / 5000.0f;
  365. query->fov = 45.0f;
  366. mCameraMatrix.setColumn( 3, mCameraPos );
  367. query->cameraMatrix = mCameraMatrix;
  368. return true;
  369. }
  370. //------------------------------------------------------------------------------
  371. void GuiObjectView::onMouseEnter( const GuiEvent & event )
  372. {
  373. onMouseEnter_callback();
  374. }
  375. //------------------------------------------------------------------------------
  376. void GuiObjectView::onMouseLeave( const GuiEvent & event )
  377. {
  378. onMouseLeave_callback();
  379. }
  380. //------------------------------------------------------------------------------
  381. void GuiObjectView::renderWorld( const RectI& updateRect )
  382. {
  383. if( !mModel )
  384. return;
  385. GFXTransformSaver _saveTransforms;
  386. // Determine the camera position, and store off render state.
  387. MatrixF modelview;
  388. MatrixF mv;
  389. Point3F cp;
  390. modelview = GFX->getWorldMatrix();
  391. mv = modelview;
  392. mv.inverse();
  393. mv.getColumn( 3, &cp );
  394. RenderPassManager* renderPass = gClientSceneGraph->getDefaultRenderPass();
  395. S32 time = Platform::getVirtualMilliseconds();
  396. S32 dt = time - mLastRenderTime;
  397. mLastRenderTime = time;
  398. LIGHTMGR->unregisterAllLights();
  399. LIGHTMGR->setSpecialLight( LightManager::slSunLightType, mLight );
  400. GFX->setStateBlock( mDefaultGuiSB );
  401. F32 left, right, top, bottom, nearPlane, farPlane;
  402. bool isOrtho;
  403. GFX->getFrustum( &left, &right, &bottom, &top, &nearPlane, &farPlane, &isOrtho );
  404. Frustum frust( false, left, right, top, bottom, nearPlane, farPlane, MatrixF::Identity );
  405. SceneRenderState state
  406. (
  407. gClientSceneGraph,
  408. SPT_Diffuse,
  409. SceneCameraState( GFX->getViewport(), frust, MatrixF::Identity, GFX->getProjectionMatrix() ),
  410. renderPass,
  411. true
  412. );
  413. // Set up our TS render state here.
  414. TSRenderState rdata;
  415. rdata.setSceneState( &state );
  416. // We might have some forward lit materials
  417. // so pass down a query to gather lights.
  418. LightQuery query;
  419. query.init( SphereF( Point3F::Zero, 1.0f ) );
  420. rdata.setLightQuery( &query );
  421. // Render primary model.
  422. if( mModel )
  423. {
  424. if( mRunThread )
  425. {
  426. mModel->advanceTime( dt / 1000.f, mRunThread );
  427. mModel->animate();
  428. }
  429. mModel->render( rdata );
  430. }
  431. // Render mounted model.
  432. if( mMountedModel && mMountNode != -1 )
  433. {
  434. GFX->pushWorldMatrix();
  435. GFX->multWorld( mModel->mNodeTransforms[ mMountNode ] );
  436. GFX->multWorld( mMountTransform );
  437. mMountedModel->render( rdata );
  438. GFX->popWorldMatrix();
  439. }
  440. renderPass->renderPass( &state );
  441. // Make sure to remove our fake sun.
  442. LIGHTMGR->unregisterAllLights();
  443. }
  444. //------------------------------------------------------------------------------
  445. void GuiObjectView::setOrbitDistance( F32 distance )
  446. {
  447. // Make sure the orbit distance is within the acceptable range
  448. mOrbitDist = mClampF( distance, mMinOrbitDist, mMaxOrbitDist );
  449. }
  450. //------------------------------------------------------------------------------
  451. void GuiObjectView::setCameraSpeed( F32 factor )
  452. {
  453. mCameraSpeed = factor;
  454. }
  455. //------------------------------------------------------------------------------
  456. void GuiObjectView::setCameraRotation( const EulerF& rotation )
  457. {
  458. mCameraRot.set(rotation);
  459. }
  460. //------------------------------------------------------------------------------
  461. void GuiObjectView::setLightColor( const LinearColorF& color )
  462. {
  463. mLightColor = color;
  464. if( mLight )
  465. mLight->setColor( color );
  466. }
  467. //------------------------------------------------------------------------------
  468. void GuiObjectView::setLightAmbient( const LinearColorF& color )
  469. {
  470. mLightAmbient = color;
  471. if( mLight )
  472. mLight->setAmbient( color );
  473. }
  474. //------------------------------------------------------------------------------
  475. void GuiObjectView::setLightDirection( const Point3F& direction )
  476. {
  477. mLightDirection = direction;
  478. if( mLight )
  479. mLight->setDirection( direction );
  480. }
  481. //------------------------------------------------------------------------------
  482. void GuiObjectView::_initAnimation()
  483. {
  484. AssertFatal( mModel, "GuiObjectView::_initAnimation - No model loaded!" );
  485. if( mAnimationSeqName.isEmpty() && mAnimationSeq == -1 )
  486. return;
  487. // Look up sequence by name.
  488. if( !mAnimationSeqName.isEmpty() )
  489. {
  490. mAnimationSeq = mModel->getShape()->findSequence( mAnimationSeqName );
  491. if( mAnimationSeq == -1 )
  492. {
  493. Con::errorf( "GuiObjectView::_initAnimation - Cannot find animation sequence '%s' on '%s'",
  494. mAnimationSeqName.c_str(),
  495. mModelName
  496. );
  497. return;
  498. }
  499. }
  500. // Start sequence.
  501. if( mAnimationSeq != -1 )
  502. {
  503. if( mAnimationSeq >= mModel->getShape()->sequences.size() )
  504. {
  505. Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'",
  506. mAnimationSeq,
  507. mModelName
  508. );
  509. mAnimationSeq = -1;
  510. return;
  511. }
  512. if( !mRunThread )
  513. mRunThread = mModel->addThread();
  514. mModel->setSequence( mRunThread, mAnimationSeq, 0.f );
  515. }
  516. mLastRenderTime = Platform::getVirtualMilliseconds();
  517. }
  518. //------------------------------------------------------------------------------
  519. void GuiObjectView::_initMount()
  520. {
  521. AssertFatal( mModel, "GuiObjectView::_initMount - No model loaded!" );
  522. if( !mMountedModel )
  523. return;
  524. mMountTransform.identity();
  525. // Look up the node to which to mount to.
  526. if( !mMountNodeName.isEmpty() )
  527. {
  528. mMountNode = mModel->getShape()->findNode( mMountNodeName );
  529. if( mMountNode == -1 )
  530. {
  531. Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'",
  532. mMountNodeName.c_str(),
  533. mModelName
  534. );
  535. return;
  536. }
  537. }
  538. // Make sure mount node is valid.
  539. if( mMountNode != -1 && mMountNode >= mModel->getShape()->nodes.size() )
  540. {
  541. Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'",
  542. mMountNode,
  543. mModelName
  544. );
  545. mMountNode = -1;
  546. return;
  547. }
  548. // Look up node on the mounted model from
  549. // which to mount to the primary model's node.
  550. S32 mountPoint = mMountedModel->getShape()->findNode( "mountPoint" );
  551. if( mountPoint != -1 )
  552. {
  553. mMountedModel->getShape()->getNodeWorldTransform( mountPoint, &mMountTransform ),
  554. mMountTransform.inverse();
  555. }
  556. }
  557. //=============================================================================
  558. // Console Methods.
  559. //=============================================================================
  560. // MARK: ---- Console Methods ----
  561. //-----------------------------------------------------------------------------
  562. DefineEngineMethod( GuiObjectView, getModel, const char*, (),,
  563. "@brief Return the model displayed in this view.\n\n"
  564. "@tsexample\n"
  565. "// Request the displayed model name from the GuiObjectView object.\n"
  566. "%modelName = %thisGuiObjectView.getModel();\n"
  567. "@endtsexample\n\n"
  568. "@return Name of the displayed model.\n\n"
  569. "@see GuiControl")
  570. {
  571. return Con::getReturnBuffer( object->getModelName() );
  572. }
  573. //-----------------------------------------------------------------------------
  574. DefineEngineMethod( GuiObjectView, setModel, void, (const char* shapeName),,
  575. "@brief Sets the model to be displayed in this control.\n\n"
  576. "@param shapeName Name of the model to display.\n"
  577. "@tsexample\n"
  578. "// Define the model we want to display\n"
  579. "%shapeName = \"gideon.dts\";\n\n"
  580. "// Tell the GuiObjectView object to display the defined model\n"
  581. "%thisGuiObjectView.setModel(%shapeName);\n"
  582. "@endtsexample\n\n"
  583. "@see GuiControl")
  584. {
  585. object->setObjectModel( shapeName );
  586. }
  587. //-----------------------------------------------------------------------------
  588. DefineEngineMethod( GuiObjectView, getMountedModel, const char*, (),,
  589. "@brief Return the name of the mounted model.\n\n"
  590. "@tsexample\n"
  591. "// Request the name of the mounted model from the GuiObjectView object\n"
  592. "%mountedModelName = %thisGuiObjectView.getMountedModel();\n"
  593. "@endtsexample\n\n"
  594. "@return Name of the mounted model.\n\n"
  595. "@see GuiControl")
  596. {
  597. return Con::getReturnBuffer( object->getMountedModelName() );
  598. }
  599. //-----------------------------------------------------------------------------
  600. DefineEngineMethod( GuiObjectView, setMountedModel, void, (const char* shapeName),,
  601. "@brief Sets the model to be mounted on the primary model.\n\n"
  602. "@param shapeName Name of the model to mount.\n"
  603. "@tsexample\n"
  604. "// Define the model name to mount\n"
  605. "%modelToMount = \"GideonGlasses.dts\";\n\n"
  606. "// Inform the GuiObjectView object to mount the defined model to the existing model in the control\n"
  607. "%thisGuiObjectView.setMountedModel(%modelToMount);\n"
  608. "@endtsexample\n\n"
  609. "@see GuiControl")
  610. {
  611. object->setObjectModel(shapeName);
  612. }
  613. //-----------------------------------------------------------------------------
  614. DefineEngineMethod( GuiObjectView, getSkin, const char*, (),,
  615. "@brief Return the name of skin used on the primary model.\n\n"
  616. "@tsexample\n"
  617. "// Request the name of the skin used on the primary model in the control\n"
  618. "%skinName = %thisGuiObjectView.getSkin();\n"
  619. "@endtsexample\n\n"
  620. "@return Name of the skin used on the primary model.\n\n"
  621. "@see GuiControl")
  622. {
  623. return Con::getReturnBuffer( object->getSkin() );
  624. }
  625. //-----------------------------------------------------------------------------
  626. DefineEngineMethod( GuiObjectView, setSkin, void, (const char* skinName),,
  627. "@brief Sets the skin to use on the model being displayed.\n\n"
  628. "@param skinName Name of the skin to use.\n"
  629. "@tsexample\n"
  630. "// Define the skin we want to apply to the main model in the control\n"
  631. "%skinName = \"disco_gideon\";\n\n"
  632. "// Inform the GuiObjectView control to update the skin the to defined skin\n"
  633. "%thisGuiObjectView.setSkin(%skinName);\n"
  634. "@endtsexample\n\n"
  635. "@see GuiControl")
  636. {
  637. object->setSkin( skinName );
  638. }
  639. //-----------------------------------------------------------------------------
  640. DefineEngineMethod( GuiObjectView, getMountSkin, const char*, ( S32 param1, S32 param2),,
  641. "@brief Return the name of skin used on the mounted model.\n\n"
  642. "@tsexample\n"
  643. "// Request the skin name from the model mounted on to the main model in the control\n"
  644. "%mountModelSkin = %thisGuiObjectView.getMountSkin();\n"
  645. "@endtsexample\n\n"
  646. "@return Name of the skin used on the mounted model.\n\n"
  647. "@see GuiControl")
  648. {
  649. return Con::getReturnBuffer( object->getMountSkin() );
  650. }
  651. //-----------------------------------------------------------------------------
  652. DefineEngineMethod( GuiObjectView, setMountSkin, void, (const char* skinName),,
  653. "@brief Sets the skin to use on the mounted model.\n\n"
  654. "@param skinName Name of the skin to set on the model mounted to the main model in the control\n"
  655. "@tsexample\n"
  656. "// Define the name of the skin\n"
  657. "%skinName = \"BronzeGlasses\";\n\n"
  658. "// Inform the GuiObjectView Control of the skin to use on the mounted model\n"
  659. "%thisGuiObjectViewCtrl.setMountSkin(%skinName);\n"
  660. "@endtsexample\n\n"
  661. "@see GuiControl")
  662. {
  663. object->setMountSkin(skinName);
  664. }
  665. //-----------------------------------------------------------------------------
  666. DefineEngineMethod( GuiObjectView, setSeq, void, (const char* indexOrName),,
  667. "@brief Sets the animation to play for the viewed object.\n\n"
  668. "@param indexOrName The index or name of the animation to play.\n"
  669. "@tsexample\n"
  670. "// Set the animation index value, or animation sequence name.\n"
  671. "%indexVal = \"3\";\n"
  672. "//OR:\n"
  673. "%indexVal = \"idle\";\n\n"
  674. "// Inform the GuiObjectView object to set the animation sequence of the object in the control.\n"
  675. "%thisGuiObjectVew.setSeq(%indexVal);\n"
  676. "@endtsexample\n\n"
  677. "@see GuiControl")
  678. {
  679. if( dIsdigit( indexOrName[0] ) )
  680. object->setObjectAnimation( dAtoi( indexOrName ) );
  681. else
  682. object->setObjectAnimation( indexOrName );
  683. }
  684. //-----------------------------------------------------------------------------
  685. DefineEngineMethod( GuiObjectView, setMount, void, ( const char* shapeName, const char* mountNodeIndexOrName),,
  686. "@brief Mounts the given model to the specified mount point of the primary model displayed in this control.\n\n"
  687. "Detailed description\n\n"
  688. "@param shapeName Name of the model to mount.\n"
  689. "@param mountNodeIndexOrName Index or name of the mount point to be mounted to. If index, corresponds to \"mountN\" in your shape where N is the number passed here.\n"
  690. "@tsexample\n"
  691. "// Set the shapeName to mount\n"
  692. "%shapeName = \"GideonGlasses.dts\"\n\n"
  693. "// Set the mount node of the primary model in the control to mount the new shape at\n"
  694. "%mountNodeIndexOrName = \"3\";\n"
  695. "//OR:\n"
  696. "%mountNodeIndexOrName = \"Face\";\n\n"
  697. "// Inform the GuiObjectView object to mount the shape at the specified node.\n"
  698. "%thisGuiObjectView.setMount(%shapeName,%mountNodeIndexOrName);\n"
  699. "@endtsexample\n\n"
  700. "@see GuiControl")
  701. {
  702. if( dIsdigit( mountNodeIndexOrName[0] ) )
  703. object->setMountNode( dAtoi( mountNodeIndexOrName ) );
  704. else
  705. object->setMountNode( mountNodeIndexOrName );
  706. object->setMountedObject( shapeName );
  707. }
  708. //-----------------------------------------------------------------------------
  709. DefineEngineMethod( GuiObjectView, getOrbitDistance, F32, (),,
  710. "@brief Return the current distance at which the camera orbits the object.\n\n"
  711. "@tsexample\n"
  712. "// Request the current orbit distance\n"
  713. "%orbitDistance = %thisGuiObjectView.getOrbitDistance();\n"
  714. "@endtsexample\n\n"
  715. "@return The distance at which the camera orbits the object.\n\n"
  716. "@see GuiControl")
  717. {
  718. return object->getOrbitDistance();
  719. }
  720. //-----------------------------------------------------------------------------
  721. DefineEngineMethod( GuiObjectView, setOrbitDistance, void, (F32 distance),,
  722. "@brief Sets the distance at which the camera orbits the object. Clamped to the acceptable range defined in the class by min and max orbit distances.\n\n"
  723. "Detailed description\n\n"
  724. "@param distance The distance to set the orbit to (will be clamped).\n"
  725. "@tsexample\n"
  726. "// Define the orbit distance value\n"
  727. "%orbitDistance = \"1.5\";\n\n"
  728. "// Inform the GuiObjectView object to set the orbit distance to the defined value\n"
  729. "%thisGuiObjectView.setOrbitDistance(%orbitDistance);\n"
  730. "@endtsexample\n\n"
  731. "@see GuiControl")
  732. {
  733. object->setOrbitDistance( distance );
  734. }
  735. //-----------------------------------------------------------------------------
  736. DefineEngineMethod( GuiObjectView, getCameraSpeed, F32, (),,
  737. "@brief Return the current multiplier for camera zooming and rotation.\n\n"
  738. "@tsexample\n"
  739. "// Request the current camera zooming and rotation multiplier value\n"
  740. "%multiplier = %thisGuiObjectView.getCameraSpeed();\n"
  741. "@endtsexample\n\n"
  742. "@return Camera zooming / rotation multiplier value.\n\n"
  743. "@see GuiControl")
  744. {
  745. return object->getCameraSpeed();
  746. }
  747. //-----------------------------------------------------------------------------
  748. DefineEngineMethod( GuiObjectView, setCameraSpeed, void, (F32 factor),,
  749. "@brief Sets the multiplier for the camera rotation and zoom speed.\n\n"
  750. "@param factor Multiplier for camera rotation and zoom speed.\n"
  751. "@tsexample\n"
  752. "// Set the factor value\n"
  753. "%factor = \"0.75\";\n\n"
  754. "// Inform the GuiObjectView object to set the camera speed.\n"
  755. "%thisGuiObjectView.setCameraSpeed(%factor);\n"
  756. "@endtsexample\n\n"
  757. "@see GuiControl")
  758. {
  759. object->setCameraSpeed( factor );
  760. }
  761. //-----------------------------------------------------------------------------
  762. DefineEngineMethod( GuiObjectView, setLightColor, void, ( LinearColorF color),,
  763. "@brief Set the light color on the sun object used to render the model.\n\n"
  764. "@param color Color of sunlight.\n"
  765. "@tsexample\n"
  766. "// Set the color value for the sun\n"
  767. "%color = \"1.0 0.4 0.5\";\n\n"
  768. "// Inform the GuiObjectView object to change the sun color to the defined value\n"
  769. "%thisGuiObjectView.setLightColor(%color);\n"
  770. "@endtsexample\n\n"
  771. "@see GuiControl")
  772. {
  773. object->setLightColor( color );
  774. }
  775. //-----------------------------------------------------------------------------
  776. DefineEngineMethod( GuiObjectView, setLightAmbient, void, (LinearColorF color),,
  777. "@brief Set the light ambient color on the sun object used to render the model.\n\n"
  778. "@param color Ambient color of sunlight.\n"
  779. "@tsexample\n"
  780. "// Define the sun ambient color value\n"
  781. "%color = \"1.0 0.4 0.6\";\n\n"
  782. "// Inform the GuiObjectView object to set the sun ambient color to the requested value\n"
  783. "%thisGuiObjectView.setLightAmbient(%color);\n"
  784. "@endtsexample\n\n"
  785. "@see GuiControl")
  786. {
  787. object->setLightAmbient( color );
  788. }
  789. //-----------------------------------------------------------------------------
  790. DefineEngineMethod( GuiObjectView, setLightDirection, void, (Point3F direction),,
  791. "@brief Set the light direction from which to light the model.\n\n"
  792. "@param direction XYZ direction from which the light will shine on the model\n"
  793. "@tsexample\n"
  794. "// Set the light direction\n"
  795. "%direction = \"1.0 0.2 0.4\"\n\n"
  796. "// Inform the GuiObjectView object to change the light direction to the defined value\n"
  797. "%thisGuiObjectView.setLightDirection(%direction);\n"
  798. "@endtsexample\n\n"
  799. "@see GuiControl")
  800. {
  801. object->setLightDirection( direction );
  802. }