guiObjectView.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  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. addGroup( "Model" );
  123. addField( "shapeFile", TypeStringFilename, Offset( mModelName, GuiObjectView ),
  124. "The object model shape file to show in the view." );
  125. addField( "skin", TypeRealString, Offset( mSkinName, GuiObjectView ),
  126. "The skin to use on the object model." );
  127. endGroup( "Model" );
  128. addGroup( "Animation" );
  129. addField( "animSequence", TypeRealString, Offset( mAnimationSeqName, GuiObjectView ),
  130. "The animation sequence to play on the model." );
  131. endGroup( "Animation" );
  132. addGroup( "Mounting" );
  133. addField( "mountedShapeFile", TypeStringFilename, Offset( mMountedModelName, GuiObjectView ),
  134. "Optional shape file to mount on the primary model (e.g. weapon)." );
  135. addField( "mountedSkin", TypeRealString, Offset( mMountSkinName, GuiObjectView ),
  136. "Skin name used on mounted shape file." );
  137. addField( "mountedNode", TypeRealString, Offset( mMountNodeName, GuiObjectView ),
  138. "Name of node on primary model to which to mount the secondary shape." );
  139. endGroup( "Mounting" );
  140. addGroup( "Lighting" );
  141. addField( "lightColor", TypeColorF, Offset( mLightColor, GuiObjectView ),
  142. "Diffuse color of the sunlight used to render the model." );
  143. addField( "lightAmbient", TypeColorF, Offset( mLightAmbient, GuiObjectView ),
  144. "Ambient color of the sunlight used to render the model." );
  145. addField( "lightDirection", TypePoint3F, Offset( mLightDirection, GuiObjectView ),
  146. "Direction from which the model is illuminated." );
  147. endGroup( "Lighting" );
  148. addGroup( "Camera" );
  149. addField( "orbitDiststance", TypeF32, Offset( mOrbitDist, GuiObjectView ),
  150. "Distance from which to render the model." );
  151. addField( "minOrbitDiststance", TypeF32, Offset( mMinOrbitDist, GuiObjectView ),
  152. "Maxiumum distance to which the camera can be zoomed out." );
  153. addField( "maxOrbitDiststance", TypeF32, Offset( mMaxOrbitDist, GuiObjectView ),
  154. "Minimum distance below which the camera will not zoom in further." );
  155. addField( "cameraSpeed", TypeF32, Offset( mCameraSpeed, GuiObjectView ),
  156. "Multiplier for mouse camera operations." );
  157. addField( "cameraRotation", TypePoint3F, Offset( mCameraRotation, GuiObjectView ),
  158. "Set the camera rotation." );
  159. endGroup( "Camera" );
  160. Parent::initPersistFields();
  161. }
  162. //------------------------------------------------------------------------------
  163. void GuiObjectView::onStaticModified( StringTableEntry slotName, const char* newValue )
  164. {
  165. Parent::onStaticModified( slotName, newValue );
  166. static StringTableEntry sShapeFile = StringTable->insert( "shapeFile" );
  167. static StringTableEntry sSkin = StringTable->insert( "skin" );
  168. static StringTableEntry sMountedShapeFile = StringTable->insert( "mountedShapeFile" );
  169. static StringTableEntry sMountedSkin = StringTable->insert( "mountedSkin" );
  170. static StringTableEntry sMountedNode = StringTable->insert( "mountedNode" );
  171. static StringTableEntry sLightColor = StringTable->insert( "lightColor" );
  172. static StringTableEntry sLightAmbient = StringTable->insert( "lightAmbient" );
  173. static StringTableEntry sLightDirection = StringTable->insert( "lightDirection" );
  174. static StringTableEntry sOrbitDistance = StringTable->insert( "orbitDistance" );
  175. static StringTableEntry sMinOrbitDistance = StringTable->insert( "minOrbitDistance" );
  176. static StringTableEntry sMaxOrbitDistance = StringTable->insert( "maxOrbitDistance" );
  177. static StringTableEntry sCameraRotation = StringTable->insert( "cameraRotation" );
  178. static StringTableEntry sAnimSequence = StringTable->insert( "animSequence" );
  179. if( slotName == sShapeFile )
  180. setObjectModel( String( mModelName ) );
  181. else if( slotName == sSkin )
  182. setSkin( String( mSkinName ) );
  183. else if( slotName == sMountedShapeFile )
  184. setMountedObject( String( mMountedModelName ) );
  185. else if( slotName == sMountedSkin )
  186. setMountSkin( String( mMountSkinName ) );
  187. else if( slotName == sMountedNode )
  188. setMountNode( String( mMountNodeName ) );
  189. else if( slotName == sLightColor )
  190. setLightColor( mLightColor );
  191. else if( slotName == sLightAmbient )
  192. setLightAmbient( mLightAmbient );
  193. else if( slotName == sLightDirection )
  194. setLightDirection( mLightDirection );
  195. else if( slotName == sOrbitDistance || slotName == sMinOrbitDistance || slotName == sMaxOrbitDistance )
  196. setOrbitDistance( mOrbitDist );
  197. else if( slotName == sCameraRotation )
  198. setCameraRotation( mCameraRotation );
  199. else if( slotName == sAnimSequence )
  200. setObjectAnimation( String( mAnimationSeqName ) );
  201. }
  202. //------------------------------------------------------------------------------
  203. bool GuiObjectView::onWake()
  204. {
  205. if( !Parent::onWake() )
  206. return false;
  207. if( !mLight )
  208. {
  209. mLight = LIGHTMGR->createLightInfo();
  210. mLight->setColor( mLightColor );
  211. mLight->setAmbient( mLightAmbient );
  212. mLight->setDirection( mLightDirection );
  213. }
  214. return true;
  215. }
  216. //------------------------------------------------------------------------------
  217. void GuiObjectView::onMouseDown( const GuiEvent &event )
  218. {
  219. if( !mActive || !mVisible || !mAwake )
  220. return;
  221. mMouseState = Rotating;
  222. mLastMousePoint = event.mousePoint;
  223. mouseLock();
  224. }
  225. //------------------------------------------------------------------------------
  226. void GuiObjectView::onMouseUp( const GuiEvent &event )
  227. {
  228. mouseUnlock();
  229. mMouseState = None;
  230. }
  231. //------------------------------------------------------------------------------
  232. void GuiObjectView::onMouseDragged( const GuiEvent &event )
  233. {
  234. if( mMouseState != Rotating )
  235. return;
  236. Point2I delta = event.mousePoint - mLastMousePoint;
  237. mLastMousePoint = event.mousePoint;
  238. mCameraRot.x += ( delta.y * mCameraSpeed );
  239. mCameraRot.z += ( delta.x * mCameraSpeed );
  240. }
  241. //------------------------------------------------------------------------------
  242. void GuiObjectView::onRightMouseDown( const GuiEvent &event )
  243. {
  244. mMouseState = Zooming;
  245. mLastMousePoint = event.mousePoint;
  246. mouseLock();
  247. }
  248. //------------------------------------------------------------------------------
  249. void GuiObjectView::onRightMouseUp( const GuiEvent &event )
  250. {
  251. mouseUnlock();
  252. mMouseState = None;
  253. }
  254. //------------------------------------------------------------------------------
  255. void GuiObjectView::onRightMouseDragged( const GuiEvent &event )
  256. {
  257. if( mMouseState != Zooming )
  258. return;
  259. S32 delta = event.mousePoint.y - mLastMousePoint.y;
  260. mLastMousePoint = event.mousePoint;
  261. mOrbitDist += ( delta * mCameraSpeed );
  262. }
  263. //------------------------------------------------------------------------------
  264. void GuiObjectView::setObjectAnimation( S32 index )
  265. {
  266. mAnimationSeq = index;
  267. mAnimationSeqName = String();
  268. if( mModel )
  269. _initAnimation();
  270. }
  271. //------------------------------------------------------------------------------
  272. void GuiObjectView::setObjectAnimation( const String& sequenceName )
  273. {
  274. mAnimationSeq = -1;
  275. mAnimationSeqName = sequenceName;
  276. if( mModel )
  277. _initAnimation();
  278. }
  279. //------------------------------------------------------------------------------
  280. void GuiObjectView::setObjectModel( const String& modelName )
  281. {
  282. SAFE_DELETE( mModel );
  283. mRunThread = 0;
  284. mModelName = String::EmptyString;
  285. // Load the shape.
  286. Resource< TSShape > model = ResourceManager::get().load( modelName );
  287. if( !model )
  288. {
  289. Con::warnf( "GuiObjectView::setObjectModel - Failed to load model '%s'", modelName.c_str() );
  290. return;
  291. }
  292. // Instantiate it.
  293. mModel = new TSShapeInstance( model, true );
  294. mModelName = modelName;
  295. if( !mSkinName.isEmpty() )
  296. mModel->reSkin( mSkinName );
  297. // Initialize camera values.
  298. mOrbitPos = mModel->getShape()->center;
  299. mMinOrbitDist = mModel->getShape()->mRadius;
  300. // Initialize animation.
  301. _initAnimation();
  302. _initMount();
  303. }
  304. //------------------------------------------------------------------------------
  305. void GuiObjectView::setSkin( const String& name )
  306. {
  307. if( mModel )
  308. mModel->reSkin( name, mSkinName );
  309. mSkinName = name;
  310. }
  311. //------------------------------------------------------------------------------
  312. void GuiObjectView::setMountSkin( const String& name )
  313. {
  314. if( mMountedModel )
  315. mMountedModel->reSkin( name, mMountSkinName );
  316. mMountSkinName = name;
  317. }
  318. //------------------------------------------------------------------------------
  319. void GuiObjectView::setMountNode( S32 index )
  320. {
  321. setMountNode( String::ToString( "mount%i", index ) );
  322. }
  323. //------------------------------------------------------------------------------
  324. void GuiObjectView::setMountNode( const String& name )
  325. {
  326. mMountNodeName = name;
  327. if( mModel )
  328. _initMount();
  329. }
  330. //------------------------------------------------------------------------------
  331. void GuiObjectView::setMountedObject( const String& modelName )
  332. {
  333. SAFE_DELETE( mMountedModel );
  334. mMountedModelName = String::EmptyString;
  335. // Load the model.
  336. Resource< TSShape > model = ResourceManager::get().load( modelName );
  337. if( !model )
  338. {
  339. Con::warnf( "GuiObjectView::setMountedObject - Failed to load object model '%s'",
  340. modelName.c_str() );
  341. return;
  342. }
  343. mMountedModel = new TSShapeInstance( model, true );
  344. mMountedModelName = modelName;
  345. if( !mMountSkinName.isEmpty() )
  346. mMountedModel->reSkin( mMountSkinName );
  347. if( mModel )
  348. _initMount();
  349. }
  350. //------------------------------------------------------------------------------
  351. bool GuiObjectView::processCameraQuery( CameraQuery* query )
  352. {
  353. // Adjust the camera so that we are still facing the model.
  354. Point3F vec;
  355. MatrixF xRot, zRot;
  356. xRot.set( EulerF( mCameraRot.x, 0.0f, 0.0f ) );
  357. zRot.set( EulerF( 0.0f, 0.0f, mCameraRot.z ) );
  358. mCameraMatrix.mul( zRot, xRot );
  359. mCameraMatrix.getColumn( 1, &vec );
  360. vec *= mOrbitDist;
  361. mCameraPos = mOrbitPos - vec;
  362. query->farPlane = 2100.0f;
  363. query->nearPlane = query->farPlane / 5000.0f;
  364. query->fov = 45.0f;
  365. mCameraMatrix.setColumn( 3, mCameraPos );
  366. query->cameraMatrix = mCameraMatrix;
  367. return true;
  368. }
  369. //------------------------------------------------------------------------------
  370. void GuiObjectView::onMouseEnter( const GuiEvent & event )
  371. {
  372. onMouseEnter_callback();
  373. }
  374. //------------------------------------------------------------------------------
  375. void GuiObjectView::onMouseLeave( const GuiEvent & event )
  376. {
  377. onMouseLeave_callback();
  378. }
  379. //------------------------------------------------------------------------------
  380. void GuiObjectView::renderWorld( const RectI& updateRect )
  381. {
  382. if( !mModel )
  383. return;
  384. GFXTransformSaver _saveTransforms;
  385. // Determine the camera position, and store off render state.
  386. MatrixF modelview;
  387. MatrixF mv;
  388. Point3F cp;
  389. modelview = GFX->getWorldMatrix();
  390. mv = modelview;
  391. mv.inverse();
  392. mv.getColumn( 3, &cp );
  393. RenderPassManager* renderPass = gClientSceneGraph->getDefaultRenderPass();
  394. S32 time = Platform::getVirtualMilliseconds();
  395. S32 dt = time - mLastRenderTime;
  396. mLastRenderTime = time;
  397. LIGHTMGR->unregisterAllLights();
  398. LIGHTMGR->setSpecialLight( LightManager::slSunLightType, mLight );
  399. GFX->setStateBlock( mDefaultGuiSB );
  400. F32 left, right, top, bottom, nearPlane, farPlane;
  401. bool isOrtho;
  402. GFX->getFrustum( &left, &right, &bottom, &top, &nearPlane, &farPlane, &isOrtho );
  403. Frustum frust( false, left, right, top, bottom, nearPlane, farPlane, MatrixF::Identity );
  404. SceneRenderState state
  405. (
  406. gClientSceneGraph,
  407. SPT_Diffuse,
  408. SceneCameraState( GFX->getViewport(), frust, MatrixF::Identity, GFX->getProjectionMatrix() ),
  409. renderPass,
  410. true
  411. );
  412. // Set up our TS render state here.
  413. TSRenderState rdata;
  414. rdata.setSceneState( &state );
  415. // We might have some forward lit materials
  416. // so pass down a query to gather lights.
  417. LightQuery query;
  418. query.init( SphereF( Point3F::Zero, 1.0f ) );
  419. rdata.setLightQuery( &query );
  420. // Render primary model.
  421. if( mModel )
  422. {
  423. if( mRunThread )
  424. {
  425. mModel->advanceTime( dt / 1000.f, mRunThread );
  426. mModel->animate();
  427. }
  428. mModel->render( rdata );
  429. }
  430. // Render mounted model.
  431. if( mMountedModel && mMountNode != -1 )
  432. {
  433. GFX->pushWorldMatrix();
  434. GFX->multWorld( mModel->mNodeTransforms[ mMountNode ] );
  435. GFX->multWorld( mMountTransform );
  436. mMountedModel->render( rdata );
  437. GFX->popWorldMatrix();
  438. }
  439. renderPass->renderPass( &state );
  440. // Make sure to remove our fake sun.
  441. LIGHTMGR->unregisterAllLights();
  442. }
  443. //------------------------------------------------------------------------------
  444. void GuiObjectView::setOrbitDistance( F32 distance )
  445. {
  446. // Make sure the orbit distance is within the acceptable range
  447. mOrbitDist = mClampF( distance, mMinOrbitDist, mMaxOrbitDist );
  448. }
  449. //------------------------------------------------------------------------------
  450. void GuiObjectView::setCameraSpeed( F32 factor )
  451. {
  452. mCameraSpeed = factor;
  453. }
  454. //------------------------------------------------------------------------------
  455. void GuiObjectView::setCameraRotation( const EulerF& rotation )
  456. {
  457. mCameraRot.set(rotation);
  458. }
  459. //------------------------------------------------------------------------------
  460. void GuiObjectView::setLightColor( const LinearColorF& color )
  461. {
  462. mLightColor = color;
  463. if( mLight )
  464. mLight->setColor( color );
  465. }
  466. //------------------------------------------------------------------------------
  467. void GuiObjectView::setLightAmbient( const LinearColorF& color )
  468. {
  469. mLightAmbient = color;
  470. if( mLight )
  471. mLight->setAmbient( color );
  472. }
  473. //------------------------------------------------------------------------------
  474. void GuiObjectView::setLightDirection( const Point3F& direction )
  475. {
  476. mLightDirection = direction;
  477. if( mLight )
  478. mLight->setDirection( direction );
  479. }
  480. //------------------------------------------------------------------------------
  481. void GuiObjectView::_initAnimation()
  482. {
  483. AssertFatal( mModel, "GuiObjectView::_initAnimation - No model loaded!" );
  484. if( mAnimationSeqName.isEmpty() && mAnimationSeq == -1 )
  485. return;
  486. // Look up sequence by name.
  487. if( !mAnimationSeqName.isEmpty() )
  488. {
  489. mAnimationSeq = mModel->getShape()->findSequence( mAnimationSeqName );
  490. if( mAnimationSeq == -1 )
  491. {
  492. Con::errorf( "GuiObjectView::_initAnimation - Cannot find animation sequence '%s' on '%s'",
  493. mAnimationSeqName.c_str(),
  494. mModelName.c_str()
  495. );
  496. return;
  497. }
  498. }
  499. // Start sequence.
  500. if( mAnimationSeq != -1 )
  501. {
  502. if( mAnimationSeq >= mModel->getShape()->sequences.size() )
  503. {
  504. Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'",
  505. mAnimationSeq,
  506. mModelName.c_str()
  507. );
  508. mAnimationSeq = -1;
  509. return;
  510. }
  511. if( !mRunThread )
  512. mRunThread = mModel->addThread();
  513. mModel->setSequence( mRunThread, mAnimationSeq, 0.f );
  514. }
  515. mLastRenderTime = Platform::getVirtualMilliseconds();
  516. }
  517. //------------------------------------------------------------------------------
  518. void GuiObjectView::_initMount()
  519. {
  520. AssertFatal( mModel, "GuiObjectView::_initMount - No model loaded!" );
  521. if( !mMountedModel )
  522. return;
  523. mMountTransform.identity();
  524. // Look up the node to which to mount to.
  525. if( !mMountNodeName.isEmpty() )
  526. {
  527. mMountNode = mModel->getShape()->findNode( mMountNodeName );
  528. if( mMountNode == -1 )
  529. {
  530. Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'",
  531. mMountNodeName.c_str(),
  532. mModelName.c_str()
  533. );
  534. return;
  535. }
  536. }
  537. // Make sure mount node is valid.
  538. if( mMountNode != -1 && mMountNode >= mModel->getShape()->nodes.size() )
  539. {
  540. Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'",
  541. mMountNode,
  542. mModelName.c_str()
  543. );
  544. mMountNode = -1;
  545. return;
  546. }
  547. // Look up node on the mounted model from
  548. // which to mount to the primary model's node.
  549. S32 mountPoint = mMountedModel->getShape()->findNode( "mountPoint" );
  550. if( mountPoint != -1 )
  551. {
  552. mMountedModel->getShape()->getNodeWorldTransform( mountPoint, &mMountTransform ),
  553. mMountTransform.inverse();
  554. }
  555. }
  556. //=============================================================================
  557. // Console Methods.
  558. //=============================================================================
  559. // MARK: ---- Console Methods ----
  560. //-----------------------------------------------------------------------------
  561. DefineEngineMethod( GuiObjectView, getModel, const char*, (),,
  562. "@brief Return the model displayed in this view.\n\n"
  563. "@tsexample\n"
  564. "// Request the displayed model name from the GuiObjectView object.\n"
  565. "%modelName = %thisGuiObjectView.getModel();\n"
  566. "@endtsexample\n\n"
  567. "@return Name of the displayed model.\n\n"
  568. "@see GuiControl")
  569. {
  570. return Con::getReturnBuffer( object->getModelName() );
  571. }
  572. //-----------------------------------------------------------------------------
  573. DefineEngineMethod( GuiObjectView, setModel, void, (const char* shapeName),,
  574. "@brief Sets the model to be displayed in this control.\n\n"
  575. "@param shapeName Name of the model to display.\n"
  576. "@tsexample\n"
  577. "// Define the model we want to display\n"
  578. "%shapeName = \"gideon.dts\";\n\n"
  579. "// Tell the GuiObjectView object to display the defined model\n"
  580. "%thisGuiObjectView.setModel(%shapeName);\n"
  581. "@endtsexample\n\n"
  582. "@see GuiControl")
  583. {
  584. object->setObjectModel( shapeName );
  585. }
  586. //-----------------------------------------------------------------------------
  587. DefineEngineMethod( GuiObjectView, getMountedModel, const char*, (),,
  588. "@brief Return the name of the mounted model.\n\n"
  589. "@tsexample\n"
  590. "// Request the name of the mounted model from the GuiObjectView object\n"
  591. "%mountedModelName = %thisGuiObjectView.getMountedModel();\n"
  592. "@endtsexample\n\n"
  593. "@return Name of the mounted model.\n\n"
  594. "@see GuiControl")
  595. {
  596. return Con::getReturnBuffer( object->getMountedModelName() );
  597. }
  598. //-----------------------------------------------------------------------------
  599. DefineEngineMethod( GuiObjectView, setMountedModel, void, (const char* shapeName),,
  600. "@brief Sets the model to be mounted on the primary model.\n\n"
  601. "@param shapeName Name of the model to mount.\n"
  602. "@tsexample\n"
  603. "// Define the model name to mount\n"
  604. "%modelToMount = \"GideonGlasses.dts\";\n\n"
  605. "// Inform the GuiObjectView object to mount the defined model to the existing model in the control\n"
  606. "%thisGuiObjectView.setMountedModel(%modelToMount);\n"
  607. "@endtsexample\n\n"
  608. "@see GuiControl")
  609. {
  610. object->setObjectModel(shapeName);
  611. }
  612. //-----------------------------------------------------------------------------
  613. DefineEngineMethod( GuiObjectView, getSkin, const char*, (),,
  614. "@brief Return the name of skin used on the primary model.\n\n"
  615. "@tsexample\n"
  616. "// Request the name of the skin used on the primary model in the control\n"
  617. "%skinName = %thisGuiObjectView.getSkin();\n"
  618. "@endtsexample\n\n"
  619. "@return Name of the skin used on the primary model.\n\n"
  620. "@see GuiControl")
  621. {
  622. return Con::getReturnBuffer( object->getSkin() );
  623. }
  624. //-----------------------------------------------------------------------------
  625. DefineEngineMethod( GuiObjectView, setSkin, void, (const char* skinName),,
  626. "@brief Sets the skin to use on the model being displayed.\n\n"
  627. "@param skinName Name of the skin to use.\n"
  628. "@tsexample\n"
  629. "// Define the skin we want to apply to the main model in the control\n"
  630. "%skinName = \"disco_gideon\";\n\n"
  631. "// Inform the GuiObjectView control to update the skin the to defined skin\n"
  632. "%thisGuiObjectView.setSkin(%skinName);\n"
  633. "@endtsexample\n\n"
  634. "@see GuiControl")
  635. {
  636. object->setSkin( skinName );
  637. }
  638. //-----------------------------------------------------------------------------
  639. DefineEngineMethod( GuiObjectView, getMountSkin, const char*, ( S32 param1, S32 param2),,
  640. "@brief Return the name of skin used on the mounted model.\n\n"
  641. "@tsexample\n"
  642. "// Request the skin name from the model mounted on to the main model in the control\n"
  643. "%mountModelSkin = %thisGuiObjectView.getMountSkin();\n"
  644. "@endtsexample\n\n"
  645. "@return Name of the skin used on the mounted model.\n\n"
  646. "@see GuiControl")
  647. {
  648. return Con::getReturnBuffer( object->getMountSkin() );
  649. }
  650. //-----------------------------------------------------------------------------
  651. DefineEngineMethod( GuiObjectView, setMountSkin, void, (const char* skinName),,
  652. "@brief Sets the skin to use on the mounted model.\n\n"
  653. "@param skinName Name of the skin to set on the model mounted to the main model in the control\n"
  654. "@tsexample\n"
  655. "// Define the name of the skin\n"
  656. "%skinName = \"BronzeGlasses\";\n\n"
  657. "// Inform the GuiObjectView Control of the skin to use on the mounted model\n"
  658. "%thisGuiObjectViewCtrl.setMountSkin(%skinName);\n"
  659. "@endtsexample\n\n"
  660. "@see GuiControl")
  661. {
  662. object->setMountSkin(skinName);
  663. }
  664. //-----------------------------------------------------------------------------
  665. DefineEngineMethod( GuiObjectView, setSeq, void, (const char* indexOrName),,
  666. "@brief Sets the animation to play for the viewed object.\n\n"
  667. "@param indexOrName The index or name of the animation to play.\n"
  668. "@tsexample\n"
  669. "// Set the animation index value, or animation sequence name.\n"
  670. "%indexVal = \"3\";\n"
  671. "//OR:\n"
  672. "%indexVal = \"idle\";\n\n"
  673. "// Inform the GuiObjectView object to set the animation sequence of the object in the control.\n"
  674. "%thisGuiObjectVew.setSeq(%indexVal);\n"
  675. "@endtsexample\n\n"
  676. "@see GuiControl")
  677. {
  678. if( dIsdigit( indexOrName[0] ) )
  679. object->setObjectAnimation( dAtoi( indexOrName ) );
  680. else
  681. object->setObjectAnimation( indexOrName );
  682. }
  683. //-----------------------------------------------------------------------------
  684. DefineEngineMethod( GuiObjectView, setMount, void, ( const char* shapeName, const char* mountNodeIndexOrName),,
  685. "@brief Mounts the given model to the specified mount point of the primary model displayed in this control.\n\n"
  686. "Detailed description\n\n"
  687. "@param shapeName Name of the model to mount.\n"
  688. "@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"
  689. "@tsexample\n"
  690. "// Set the shapeName to mount\n"
  691. "%shapeName = \"GideonGlasses.dts\"\n\n"
  692. "// Set the mount node of the primary model in the control to mount the new shape at\n"
  693. "%mountNodeIndexOrName = \"3\";\n"
  694. "//OR:\n"
  695. "%mountNodeIndexOrName = \"Face\";\n\n"
  696. "// Inform the GuiObjectView object to mount the shape at the specified node.\n"
  697. "%thisGuiObjectView.setMount(%shapeName,%mountNodeIndexOrName);\n"
  698. "@endtsexample\n\n"
  699. "@see GuiControl")
  700. {
  701. if( dIsdigit( mountNodeIndexOrName[0] ) )
  702. object->setMountNode( dAtoi( mountNodeIndexOrName ) );
  703. else
  704. object->setMountNode( mountNodeIndexOrName );
  705. object->setMountedObject( shapeName );
  706. }
  707. //-----------------------------------------------------------------------------
  708. DefineEngineMethod( GuiObjectView, getOrbitDistance, F32, (),,
  709. "@brief Return the current distance at which the camera orbits the object.\n\n"
  710. "@tsexample\n"
  711. "// Request the current orbit distance\n"
  712. "%orbitDistance = %thisGuiObjectView.getOrbitDistance();\n"
  713. "@endtsexample\n\n"
  714. "@return The distance at which the camera orbits the object.\n\n"
  715. "@see GuiControl")
  716. {
  717. return object->getOrbitDistance();
  718. }
  719. //-----------------------------------------------------------------------------
  720. DefineEngineMethod( GuiObjectView, setOrbitDistance, void, (F32 distance),,
  721. "@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"
  722. "Detailed description\n\n"
  723. "@param distance The distance to set the orbit to (will be clamped).\n"
  724. "@tsexample\n"
  725. "// Define the orbit distance value\n"
  726. "%orbitDistance = \"1.5\";\n\n"
  727. "// Inform the GuiObjectView object to set the orbit distance to the defined value\n"
  728. "%thisGuiObjectView.setOrbitDistance(%orbitDistance);\n"
  729. "@endtsexample\n\n"
  730. "@see GuiControl")
  731. {
  732. object->setOrbitDistance( distance );
  733. }
  734. //-----------------------------------------------------------------------------
  735. DefineEngineMethod( GuiObjectView, getCameraSpeed, F32, (),,
  736. "@brief Return the current multiplier for camera zooming and rotation.\n\n"
  737. "@tsexample\n"
  738. "// Request the current camera zooming and rotation multiplier value\n"
  739. "%multiplier = %thisGuiObjectView.getCameraSpeed();\n"
  740. "@endtsexample\n\n"
  741. "@return Camera zooming / rotation multiplier value.\n\n"
  742. "@see GuiControl")
  743. {
  744. return object->getCameraSpeed();
  745. }
  746. //-----------------------------------------------------------------------------
  747. DefineEngineMethod( GuiObjectView, setCameraSpeed, void, (F32 factor),,
  748. "@brief Sets the multiplier for the camera rotation and zoom speed.\n\n"
  749. "@param factor Multiplier for camera rotation and zoom speed.\n"
  750. "@tsexample\n"
  751. "// Set the factor value\n"
  752. "%factor = \"0.75\";\n\n"
  753. "// Inform the GuiObjectView object to set the camera speed.\n"
  754. "%thisGuiObjectView.setCameraSpeed(%factor);\n"
  755. "@endtsexample\n\n"
  756. "@see GuiControl")
  757. {
  758. object->setCameraSpeed( factor );
  759. }
  760. //-----------------------------------------------------------------------------
  761. DefineEngineMethod( GuiObjectView, setLightColor, void, ( LinearColorF color),,
  762. "@brief Set the light color on the sun object used to render the model.\n\n"
  763. "@param color Color of sunlight.\n"
  764. "@tsexample\n"
  765. "// Set the color value for the sun\n"
  766. "%color = \"1.0 0.4 0.5\";\n\n"
  767. "// Inform the GuiObjectView object to change the sun color to the defined value\n"
  768. "%thisGuiObjectView.setLightColor(%color);\n"
  769. "@endtsexample\n\n"
  770. "@see GuiControl")
  771. {
  772. object->setLightColor( color );
  773. }
  774. //-----------------------------------------------------------------------------
  775. DefineEngineMethod( GuiObjectView, setLightAmbient, void, (LinearColorF color),,
  776. "@brief Set the light ambient color on the sun object used to render the model.\n\n"
  777. "@param color Ambient color of sunlight.\n"
  778. "@tsexample\n"
  779. "// Define the sun ambient color value\n"
  780. "%color = \"1.0 0.4 0.6\";\n\n"
  781. "// Inform the GuiObjectView object to set the sun ambient color to the requested value\n"
  782. "%thisGuiObjectView.setLightAmbient(%color);\n"
  783. "@endtsexample\n\n"
  784. "@see GuiControl")
  785. {
  786. object->setLightAmbient( color );
  787. }
  788. //-----------------------------------------------------------------------------
  789. DefineEngineMethod( GuiObjectView, setLightDirection, void, (Point3F direction),,
  790. "@brief Set the light direction from which to light the model.\n\n"
  791. "@param direction XYZ direction from which the light will shine on the model\n"
  792. "@tsexample\n"
  793. "// Set the light direction\n"
  794. "%direction = \"1.0 0.2 0.4\"\n\n"
  795. "// Inform the GuiObjectView object to change the light direction to the defined value\n"
  796. "%thisGuiObjectView.setLightDirection(%direction);\n"
  797. "@endtsexample\n\n"
  798. "@see GuiControl")
  799. {
  800. object->setLightDirection( direction );
  801. }