Scene.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. #include "Base.h"
  2. #include "AudioListener.h"
  3. #include "Scene.h"
  4. #include "SceneLoader.h"
  5. #include "MeshSkin.h"
  6. #include "Joint.h"
  7. #include "Terrain.h"
  8. namespace gameplay
  9. {
  10. // Global list of active scenes
  11. static std::vector<Scene*> __sceneList;
  12. Scene::Scene(const char* id)
  13. : _id(id ? id : ""), _activeCamera(NULL), _firstNode(NULL), _lastNode(NULL), _nodeCount(0),
  14. _lightColor(1,1,1), _lightDirection(0,-1,0), _bindAudioListenerToCamera(true), _debugBatch(NULL)
  15. {
  16. __sceneList.push_back(this);
  17. }
  18. Scene::~Scene()
  19. {
  20. // Unbind our active camera from the audio listener
  21. if (_activeCamera)
  22. {
  23. AudioListener* audioListener = AudioListener::getInstance();
  24. if (audioListener && (audioListener->getCamera() == _activeCamera))
  25. {
  26. audioListener->setCamera(NULL);
  27. }
  28. SAFE_RELEASE(_activeCamera);
  29. }
  30. // Remove all nodes from the scene
  31. removeAllNodes();
  32. SAFE_DELETE(_debugBatch);
  33. // Remove the scene from global list
  34. std::vector<Scene*>::iterator itr = std::find(__sceneList.begin(), __sceneList.end(), this);
  35. if (itr != __sceneList.end())
  36. __sceneList.erase(itr);
  37. }
  38. Scene* Scene::create(const char* id)
  39. {
  40. return new Scene(id);
  41. }
  42. Scene* Scene::load(const char* filePath)
  43. {
  44. return SceneLoader::load(filePath);
  45. }
  46. Scene* Scene::getScene(const char* id)
  47. {
  48. if (id == NULL)
  49. return __sceneList.size() ? __sceneList[0] : NULL;
  50. for (size_t i = 0, count = __sceneList.size(); i < count; ++i)
  51. {
  52. if (__sceneList[i]->_id == id)
  53. return __sceneList[i];
  54. }
  55. return NULL;
  56. }
  57. const char* Scene::getId() const
  58. {
  59. return _id.c_str();
  60. }
  61. void Scene::setId(const char* id)
  62. {
  63. _id = id ? id : "";
  64. }
  65. Node* Scene::findNode(const char* id, bool recursive, bool exactMatch) const
  66. {
  67. GP_ASSERT(id);
  68. // Search immediate children first.
  69. for (Node* child = getFirstNode(); child != NULL; child = child->getNextSibling())
  70. {
  71. // Does this child's ID match?
  72. if ((exactMatch && child->_id == id) || (!exactMatch && child->_id.find(id) == 0))
  73. {
  74. return child;
  75. }
  76. }
  77. // Recurse.
  78. if (recursive)
  79. {
  80. for (Node* child = getFirstNode(); child != NULL; child = child->getNextSibling())
  81. {
  82. Node* match = child->findNode(id, true, exactMatch);
  83. if (match)
  84. {
  85. return match;
  86. }
  87. }
  88. }
  89. return NULL;
  90. }
  91. unsigned int Scene::findNodes(const char* id, std::vector<Node*>& nodes, bool recursive, bool exactMatch) const
  92. {
  93. GP_ASSERT(id);
  94. unsigned int count = 0;
  95. // Search immediate children first.
  96. for (Node* child = getFirstNode(); child != NULL; child = child->getNextSibling())
  97. {
  98. // Does this child's ID match?
  99. if ((exactMatch && child->_id == id) || (!exactMatch && child->_id.find(id) == 0))
  100. {
  101. nodes.push_back(child);
  102. ++count;
  103. }
  104. }
  105. // Recurse.
  106. if (recursive)
  107. {
  108. for (Node* child = getFirstNode(); child != NULL; child = child->getNextSibling())
  109. {
  110. count += child->findNodes(id, nodes, true, exactMatch);
  111. }
  112. }
  113. return count;
  114. }
  115. void Scene::visitNode(Node* node, const char* visitMethod)
  116. {
  117. ScriptController* sc = Game::getInstance()->getScriptController();
  118. // Invoke the visit method for this node.
  119. if (!sc->executeFunction<bool>(visitMethod, "<Node>", node))
  120. return;
  121. // If this node has a model with a mesh skin, visit the joint hierarchy within it
  122. // since we don't add joint hierarcies directly to the scene. If joints are never
  123. // visited, it's possible that nodes embedded within the joint hierarchy that contain
  124. // models will never get visited (and therefore never get drawn).
  125. if (node->_model && node->_model->_skin && node->_model->_skin->_rootNode)
  126. {
  127. visitNode(node->_model->_skin->_rootNode, visitMethod);
  128. }
  129. // Recurse for all children.
  130. for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
  131. {
  132. visitNode(child, visitMethod);
  133. }
  134. }
  135. Node* Scene::addNode(const char* id)
  136. {
  137. Node* node = Node::create(id);
  138. GP_ASSERT(node);
  139. addNode(node);
  140. // Call release to decrement the ref count to 1 before returning.
  141. node->release();
  142. return node;
  143. }
  144. void Scene::addNode(Node* node)
  145. {
  146. GP_ASSERT(node);
  147. if (node->_scene == this)
  148. {
  149. // The node is already a member of this scene.
  150. return;
  151. }
  152. node->addRef();
  153. // If the node is part of another scene, remove it.
  154. if (node->_scene && node->_scene != this)
  155. {
  156. node->_scene->removeNode(node);
  157. }
  158. // If the node is part of another node hierarchy, remove it.
  159. if (node->getParent())
  160. {
  161. node->getParent()->removeChild(node);
  162. }
  163. // Link the new node into our list.
  164. if (_lastNode)
  165. {
  166. _lastNode->_nextSibling = node;
  167. node->_prevSibling = _lastNode;
  168. _lastNode = node;
  169. }
  170. else
  171. {
  172. _firstNode = _lastNode = node;
  173. }
  174. node->_scene = this;
  175. ++_nodeCount;
  176. // If we don't have an active camera set, then check for one and set it.
  177. if (_activeCamera == NULL)
  178. {
  179. Camera* camera = node->getCamera();
  180. if (camera)
  181. {
  182. setActiveCamera(camera);
  183. }
  184. }
  185. }
  186. void Scene::removeNode(Node* node)
  187. {
  188. GP_ASSERT(node);
  189. if (node->_scene != this)
  190. return;
  191. if (node == _firstNode)
  192. {
  193. _firstNode = node->_nextSibling;
  194. }
  195. if (node == _lastNode)
  196. {
  197. _lastNode = node->_prevSibling;
  198. }
  199. node->remove();
  200. node->_scene = NULL;
  201. SAFE_RELEASE(node);
  202. --_nodeCount;
  203. }
  204. void Scene::removeAllNodes()
  205. {
  206. while (_lastNode)
  207. {
  208. removeNode(_lastNode);
  209. }
  210. }
  211. unsigned int Scene::getNodeCount() const
  212. {
  213. return _nodeCount;
  214. }
  215. Node* Scene::getFirstNode() const
  216. {
  217. return _firstNode;
  218. }
  219. Camera* Scene::getActiveCamera() const
  220. {
  221. return _activeCamera;
  222. }
  223. void Scene::setActiveCamera(Camera* camera)
  224. {
  225. // Make sure we don't release the camera if the same camera is set twice.
  226. if (_activeCamera != camera)
  227. {
  228. AudioListener* audioListener = AudioListener::getInstance();
  229. if (_activeCamera)
  230. {
  231. // Unbind the active camera from the audio listener
  232. if (audioListener && (audioListener->getCamera() == _activeCamera))
  233. {
  234. audioListener->setCamera(NULL);
  235. }
  236. SAFE_RELEASE(_activeCamera);
  237. }
  238. _activeCamera = camera;
  239. if (_activeCamera)
  240. {
  241. _activeCamera->addRef();
  242. if (audioListener && _bindAudioListenerToCamera)
  243. {
  244. audioListener->setCamera(_activeCamera);
  245. }
  246. }
  247. }
  248. }
  249. void Scene::bindAudioListenerToCamera(bool bind)
  250. {
  251. if (_bindAudioListenerToCamera != bind)
  252. {
  253. _bindAudioListenerToCamera = bind;
  254. if (AudioListener::getInstance())
  255. {
  256. AudioListener::getInstance()->setCamera(bind ? _activeCamera : NULL);
  257. }
  258. }
  259. }
  260. const Vector3& Scene::getAmbientColor() const
  261. {
  262. return _ambientColor;
  263. }
  264. void Scene::setAmbientColor(float red, float green, float blue)
  265. {
  266. _ambientColor.set(red, green, blue);
  267. }
  268. const Vector3& Scene::getLightColor() const
  269. {
  270. return _lightColor;
  271. }
  272. void Scene::setLightColor(float red, float green, float blue)
  273. {
  274. _lightColor.set(red, green, blue);
  275. }
  276. const Vector3& Scene::getLightDirection() const
  277. {
  278. return _lightDirection;
  279. }
  280. void Scene::setLightDirection(const Vector3& direction)
  281. {
  282. _lightDirection = direction;
  283. }
  284. static Material* createDebugMaterial()
  285. {
  286. // Vertex shader for drawing colored lines.
  287. const char* vs_str =
  288. {
  289. "uniform mat4 u_viewProjectionMatrix;\n"
  290. "attribute vec4 a_position;\n"
  291. "attribute vec4 a_color;\n"
  292. "varying vec4 v_color;\n"
  293. "void main(void) {\n"
  294. " v_color = a_color;\n"
  295. " gl_Position = u_viewProjectionMatrix * a_position;\n"
  296. "}"
  297. };
  298. // Fragment shader for drawing colored lines.
  299. const char* fs_str =
  300. {
  301. #ifdef OPENGL_ES
  302. "precision highp float;\n"
  303. #endif
  304. "varying vec4 v_color;\n"
  305. "void main(void) {\n"
  306. " gl_FragColor = v_color;\n"
  307. "}"
  308. };
  309. Effect* effect = Effect::createFromSource(vs_str, fs_str);
  310. Material* material = Material::create(effect);
  311. GP_ASSERT(material && material->getStateBlock());
  312. material->getStateBlock()->setDepthTest(true);
  313. SAFE_RELEASE(effect);
  314. return material;
  315. }
  316. /**
  317. * DebugVertex structure.
  318. * @script{ignore}
  319. */
  320. struct DebugVertex
  321. {
  322. /**
  323. * The x coordinate of the vertex.
  324. */
  325. float x;
  326. /**
  327. * The y coordinate of the vertex.
  328. */
  329. float y;
  330. /**
  331. * The z coordinate of the vertex.
  332. */
  333. float z;
  334. /**
  335. * The red color component of the vertex.
  336. */
  337. float r;
  338. /**
  339. * The green color component of the vertex.
  340. */
  341. float g;
  342. /**
  343. * The blue color component of the vertex.
  344. */
  345. float b;
  346. /**
  347. * The alpha component of the vertex.
  348. */
  349. float a;
  350. };
  351. static void drawDebugLine(MeshBatch* batch, const Vector3& point1, const Vector3& point2, const Vector3& color)
  352. {
  353. GP_ASSERT(batch);
  354. static DebugVertex verts[2];
  355. verts[0].x = point1.x;
  356. verts[0].y = point1.y;
  357. verts[0].z = point1.z;
  358. verts[0].r = color.x;
  359. verts[0].g = color.y;
  360. verts[0].b = color.z;
  361. verts[0].a = 1.0f;
  362. verts[1].x = point2.x;
  363. verts[1].y = point2.y;
  364. verts[1].z = point2.z;
  365. verts[1].r = color.x;
  366. verts[1].g = color.y;
  367. verts[1].b = color.z;
  368. verts[1].a = 1.0f;
  369. batch->add(verts, 2);
  370. }
  371. #define DEBUG_BOX_COLOR Vector3(0, 1, 0)
  372. #define DEBUG_SPHERE_COLOR Vector3(0, 1, 0)
  373. static void drawDebugBox(MeshBatch* batch, const BoundingBox& box, const Matrix& matrix)
  374. {
  375. if (box.isEmpty())
  376. return;
  377. // Transform box into world space (since we only store local boxes on mesh)
  378. BoundingBox worldSpaceBox(box);
  379. worldSpaceBox.transform(matrix);
  380. // Get box corners
  381. static Vector3 corners[8];
  382. worldSpaceBox.getCorners(corners);
  383. // Draw box lines
  384. drawDebugLine(batch, corners[0], corners[1], DEBUG_BOX_COLOR);
  385. drawDebugLine(batch, corners[1], corners[2], DEBUG_BOX_COLOR);
  386. drawDebugLine(batch, corners[2], corners[3], DEBUG_BOX_COLOR);
  387. drawDebugLine(batch, corners[3], corners[0], DEBUG_BOX_COLOR);
  388. drawDebugLine(batch, corners[4], corners[5], DEBUG_BOX_COLOR);
  389. drawDebugLine(batch, corners[5], corners[6], DEBUG_BOX_COLOR);
  390. drawDebugLine(batch, corners[6], corners[7], DEBUG_BOX_COLOR);
  391. drawDebugLine(batch, corners[7], corners[4], DEBUG_BOX_COLOR);
  392. drawDebugLine(batch, corners[0], corners[7], DEBUG_BOX_COLOR);
  393. drawDebugLine(batch, corners[1], corners[6], DEBUG_BOX_COLOR);
  394. drawDebugLine(batch, corners[2], corners[5], DEBUG_BOX_COLOR);
  395. drawDebugLine(batch, corners[3], corners[4], DEBUG_BOX_COLOR);
  396. }
  397. static void drawDebugSphere(MeshBatch* batch, const BoundingSphere& sphere)
  398. {
  399. if (sphere.isEmpty())
  400. return;
  401. // Draw three rings for the sphere (one for the x, y and z axes)
  402. Vector3 pos1, pos2;
  403. float step = MATH_PI * 0.2f;
  404. float max = MATH_PIX2 + step;
  405. // X ring
  406. for (float r = 0.0f; r < max; r += step)
  407. {
  408. pos2.x = sphere.center.x;
  409. pos2.y = sphere.center.y + std::cos(r) * sphere.radius;
  410. pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
  411. if (r > 0)
  412. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  413. pos1 = pos2;
  414. }
  415. // Y ring
  416. for (float r = 0.0f; r < max; r += step)
  417. {
  418. pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
  419. pos2.y = sphere.center.y;
  420. pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
  421. if (r > 0)
  422. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  423. pos1 = pos2;
  424. }
  425. // Z ring
  426. for (float r = 0.0f; r < max; r += step)
  427. {
  428. pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
  429. pos2.y = sphere.center.y + std::sin(r) * sphere.radius;
  430. pos2.z = sphere.center.z;
  431. if (r > 0)
  432. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  433. pos1 = pos2;
  434. }
  435. }
  436. static void drawDebugNode(Scene* scene, MeshBatch* batch, Node* node, unsigned int debugFlags)
  437. {
  438. GP_ASSERT(node);
  439. // If the node isn't visible, don't draw its bounds
  440. Camera* camera = scene->getActiveCamera();
  441. if (camera)
  442. {
  443. const BoundingSphere& sphere = node->getBoundingSphere();
  444. if (!sphere.isEmpty() && !camera->getFrustum().intersects(sphere))
  445. return;
  446. }
  447. if (debugFlags & Scene::DEBUG_BOXES)
  448. {
  449. if (node->getModel())
  450. {
  451. Model* model = node->getModel();
  452. GP_ASSERT(model->getMesh());
  453. MeshSkin* skin = model->getSkin();
  454. if (skin && skin->getRootJoint() && skin->getRootJoint()->getParent())
  455. {
  456. // For skinned meshes that have a parent node to the skin's root joint,
  457. // we need to transform the bounding volume by that parent node's transform
  458. // as well to get the full skinned bounding volume.
  459. drawDebugBox(batch, model->getMesh()->getBoundingBox(), node->getWorldMatrix() * skin->getRootJoint()->getParent()->getWorldMatrix());
  460. }
  461. else
  462. {
  463. drawDebugBox(batch, model->getMesh()->getBoundingBox(), node->getWorldMatrix());
  464. }
  465. }
  466. if (node->getTerrain())
  467. {
  468. drawDebugBox(batch, node->getTerrain()->getBoundingBox(), node->getWorldMatrix());
  469. }
  470. }
  471. if (debugFlags & Scene::DEBUG_SPHERES)
  472. {
  473. drawDebugSphere(batch, node->getBoundingSphere());
  474. }
  475. for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
  476. {
  477. drawDebugNode(scene, batch, child, debugFlags);
  478. }
  479. }
  480. void Scene::drawDebug(unsigned int debugFlags)
  481. {
  482. if (_debugBatch == NULL)
  483. {
  484. Material* material = createDebugMaterial();
  485. VertexFormat::Element elements[] =
  486. {
  487. VertexFormat::Element(VertexFormat::POSITION, 3),
  488. VertexFormat::Element(VertexFormat::COLOR, 4)
  489. };
  490. _debugBatch = MeshBatch::create(VertexFormat(elements, 2), Mesh::LINES, material, false);
  491. SAFE_RELEASE(material);
  492. }
  493. _debugBatch->start();
  494. for (Node* node = _firstNode; node != NULL; node = node->_nextSibling)
  495. {
  496. drawDebugNode(this, _debugBatch, node, debugFlags);
  497. }
  498. _debugBatch->finish();
  499. if (_activeCamera)
  500. {
  501. GP_ASSERT(_debugBatch->getMaterial());
  502. GP_ASSERT(_debugBatch->getMaterial()->getParameter("u_viewProjectionMatrix"));
  503. _debugBatch->getMaterial()->getParameter("u_viewProjectionMatrix")->setValue(_activeCamera->getViewProjectionMatrix());
  504. }
  505. _debugBatch->draw();
  506. }
  507. }