guiObjectView.cpp 32 KB

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