Scene.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  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. Node* Scene::addNode(const char* id)
  116. {
  117. Node* node = Node::create(id);
  118. GP_ASSERT(node);
  119. addNode(node);
  120. // Call release to decrement the ref count to 1 before returning.
  121. node->release();
  122. return node;
  123. }
  124. void Scene::addNode(Node* node)
  125. {
  126. GP_ASSERT(node);
  127. if (node->_scene == this)
  128. {
  129. // The node is already a member of this scene.
  130. return;
  131. }
  132. node->addRef();
  133. // If the node is part of another scene, remove it.
  134. if (node->_scene && node->_scene != this)
  135. {
  136. node->_scene->removeNode(node);
  137. }
  138. // If the node is part of another node hierarchy, remove it.
  139. if (node->getParent())
  140. {
  141. node->getParent()->removeChild(node);
  142. }
  143. // Link the new node into our list.
  144. if (_lastNode)
  145. {
  146. _lastNode->_nextSibling = node;
  147. node->_prevSibling = _lastNode;
  148. _lastNode = node;
  149. }
  150. else
  151. {
  152. _firstNode = _lastNode = node;
  153. }
  154. node->_scene = this;
  155. ++_nodeCount;
  156. // If we don't have an active camera set, then check for one and set it.
  157. if (_activeCamera == NULL)
  158. {
  159. Camera* camera = node->getCamera();
  160. if (camera)
  161. {
  162. setActiveCamera(camera);
  163. }
  164. }
  165. }
  166. void Scene::removeNode(Node* node)
  167. {
  168. GP_ASSERT(node);
  169. if (node->_scene != this)
  170. return;
  171. if (node == _firstNode)
  172. {
  173. _firstNode = node->_nextSibling;
  174. }
  175. if (node == _lastNode)
  176. {
  177. _lastNode = node->_prevSibling;
  178. }
  179. node->remove();
  180. node->_scene = NULL;
  181. SAFE_RELEASE(node);
  182. --_nodeCount;
  183. }
  184. void Scene::removeAllNodes()
  185. {
  186. while (_lastNode)
  187. {
  188. removeNode(_lastNode);
  189. }
  190. }
  191. unsigned int Scene::getNodeCount() const
  192. {
  193. return _nodeCount;
  194. }
  195. Node* Scene::getFirstNode() const
  196. {
  197. return _firstNode;
  198. }
  199. Camera* Scene::getActiveCamera() const
  200. {
  201. return _activeCamera;
  202. }
  203. void Scene::setActiveCamera(Camera* camera)
  204. {
  205. // Make sure we don't release the camera if the same camera is set twice.
  206. if (_activeCamera != camera)
  207. {
  208. AudioListener* audioListener = AudioListener::getInstance();
  209. if (_activeCamera)
  210. {
  211. // Unbind the active camera from the audio listener
  212. if (audioListener && (audioListener->getCamera() == _activeCamera))
  213. {
  214. audioListener->setCamera(NULL);
  215. }
  216. SAFE_RELEASE(_activeCamera);
  217. }
  218. _activeCamera = camera;
  219. if (_activeCamera)
  220. {
  221. _activeCamera->addRef();
  222. if (audioListener && _bindAudioListenerToCamera)
  223. {
  224. audioListener->setCamera(_activeCamera);
  225. }
  226. }
  227. }
  228. }
  229. void Scene::bindAudioListenerToCamera(bool bind)
  230. {
  231. if (_bindAudioListenerToCamera != bind)
  232. {
  233. _bindAudioListenerToCamera = bind;
  234. if (AudioListener::getInstance())
  235. {
  236. AudioListener::getInstance()->setCamera(bind ? _activeCamera : NULL);
  237. }
  238. }
  239. }
  240. const Vector3& Scene::getAmbientColor() const
  241. {
  242. return _ambientColor;
  243. }
  244. void Scene::setAmbientColor(float red, float green, float blue)
  245. {
  246. _ambientColor.set(red, green, blue);
  247. }
  248. const Vector3& Scene::getLightColor() const
  249. {
  250. return _lightColor;
  251. }
  252. void Scene::setLightColor(float red, float green, float blue)
  253. {
  254. _lightColor.set(red, green, blue);
  255. }
  256. const Vector3& Scene::getLightDirection() const
  257. {
  258. return _lightDirection;
  259. }
  260. void Scene::setLightDirection(const Vector3& direction)
  261. {
  262. _lightDirection = direction;
  263. }
  264. static Material* createDebugMaterial()
  265. {
  266. // Vertex shader for drawing colored lines.
  267. const char* vs_str =
  268. {
  269. "uniform mat4 u_viewProjectionMatrix;\n"
  270. "attribute vec4 a_position;\n"
  271. "attribute vec4 a_color;\n"
  272. "varying vec4 v_color;\n"
  273. "void main(void) {\n"
  274. " v_color = a_color;\n"
  275. " gl_Position = u_viewProjectionMatrix * a_position;\n"
  276. "}"
  277. };
  278. // Fragment shader for drawing colored lines.
  279. const char* fs_str =
  280. {
  281. #ifdef OPENGL_ES
  282. "precision highp float;\n"
  283. #endif
  284. "varying vec4 v_color;\n"
  285. "void main(void) {\n"
  286. " gl_FragColor = v_color;\n"
  287. "}"
  288. };
  289. Effect* effect = Effect::createFromSource(vs_str, fs_str);
  290. Material* material = Material::create(effect);
  291. GP_ASSERT(material && material->getStateBlock());
  292. material->getStateBlock()->setDepthTest(true);
  293. SAFE_RELEASE(effect);
  294. return material;
  295. }
  296. /**
  297. * DebugVertex structure.
  298. * @script{ignore}
  299. */
  300. struct DebugVertex
  301. {
  302. /**
  303. * The x coordinate of the vertex.
  304. */
  305. float x;
  306. /**
  307. * The y coordinate of the vertex.
  308. */
  309. float y;
  310. /**
  311. * The z coordinate of the vertex.
  312. */
  313. float z;
  314. /**
  315. * The red color component of the vertex.
  316. */
  317. float r;
  318. /**
  319. * The green color component of the vertex.
  320. */
  321. float g;
  322. /**
  323. * The blue color component of the vertex.
  324. */
  325. float b;
  326. /**
  327. * The alpha component of the vertex.
  328. */
  329. float a;
  330. };
  331. static void drawDebugLine(MeshBatch* batch, const Vector3& point1, const Vector3& point2, const Vector3& color)
  332. {
  333. GP_ASSERT(batch);
  334. static DebugVertex verts[2];
  335. verts[0].x = point1.x;
  336. verts[0].y = point1.y;
  337. verts[0].z = point1.z;
  338. verts[0].r = color.x;
  339. verts[0].g = color.y;
  340. verts[0].b = color.z;
  341. verts[0].a = 1.0f;
  342. verts[1].x = point2.x;
  343. verts[1].y = point2.y;
  344. verts[1].z = point2.z;
  345. verts[1].r = color.x;
  346. verts[1].g = color.y;
  347. verts[1].b = color.z;
  348. verts[1].a = 1.0f;
  349. batch->add(verts, 2);
  350. }
  351. #define DEBUG_BOX_COLOR Vector3(0, 1, 0)
  352. #define DEBUG_SPHERE_COLOR Vector3(0, 1, 0)
  353. static void drawDebugBox(MeshBatch* batch, const BoundingBox& box, const Matrix& matrix)
  354. {
  355. if (box.isEmpty())
  356. return;
  357. // Transform box into world space (since we only store local boxes on mesh)
  358. BoundingBox worldSpaceBox(box);
  359. worldSpaceBox.transform(matrix);
  360. // Get box corners
  361. static Vector3 corners[8];
  362. worldSpaceBox.getCorners(corners);
  363. // Draw box lines
  364. drawDebugLine(batch, corners[0], corners[1], DEBUG_BOX_COLOR);
  365. drawDebugLine(batch, corners[1], corners[2], DEBUG_BOX_COLOR);
  366. drawDebugLine(batch, corners[2], corners[3], DEBUG_BOX_COLOR);
  367. drawDebugLine(batch, corners[3], corners[0], DEBUG_BOX_COLOR);
  368. drawDebugLine(batch, corners[4], corners[5], DEBUG_BOX_COLOR);
  369. drawDebugLine(batch, corners[5], corners[6], DEBUG_BOX_COLOR);
  370. drawDebugLine(batch, corners[6], corners[7], DEBUG_BOX_COLOR);
  371. drawDebugLine(batch, corners[7], corners[4], DEBUG_BOX_COLOR);
  372. drawDebugLine(batch, corners[0], corners[7], DEBUG_BOX_COLOR);
  373. drawDebugLine(batch, corners[1], corners[6], DEBUG_BOX_COLOR);
  374. drawDebugLine(batch, corners[2], corners[5], DEBUG_BOX_COLOR);
  375. drawDebugLine(batch, corners[3], corners[4], DEBUG_BOX_COLOR);
  376. }
  377. static void drawDebugSphere(MeshBatch* batch, const BoundingSphere& sphere)
  378. {
  379. if (sphere.isEmpty())
  380. return;
  381. // Draw three rings for the sphere (one for the x, y and z axes)
  382. Vector3 pos1, pos2;
  383. float step = MATH_PI * 0.2f;
  384. float max = MATH_PIX2 + step;
  385. // X ring
  386. for (float r = 0.0f; r < max; r += step)
  387. {
  388. pos2.x = sphere.center.x;
  389. pos2.y = sphere.center.y + std::cos(r) * sphere.radius;
  390. pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
  391. if (r > 0)
  392. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  393. pos1 = pos2;
  394. }
  395. // Y ring
  396. for (float r = 0.0f; r < max; r += step)
  397. {
  398. pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
  399. pos2.y = sphere.center.y;
  400. pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
  401. if (r > 0)
  402. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  403. pos1 = pos2;
  404. }
  405. // Z ring
  406. for (float r = 0.0f; r < max; r += step)
  407. {
  408. pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
  409. pos2.y = sphere.center.y + std::sin(r) * sphere.radius;
  410. pos2.z = sphere.center.z;
  411. if (r > 0)
  412. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  413. pos1 = pos2;
  414. }
  415. }
  416. static void drawDebugNode(Scene* scene, MeshBatch* batch, Node* node, unsigned int debugFlags)
  417. {
  418. GP_ASSERT(node);
  419. // If the node isn't visible, don't draw its bounds
  420. Camera* camera = scene->getActiveCamera();
  421. if (camera)
  422. {
  423. const BoundingSphere& sphere = node->getBoundingSphere();
  424. if (!sphere.isEmpty() && !camera->getFrustum().intersects(sphere))
  425. return;
  426. }
  427. if (debugFlags & Scene::DEBUG_BOXES)
  428. {
  429. if (node->getModel())
  430. {
  431. Model* model = node->getModel();
  432. GP_ASSERT(model->getMesh());
  433. MeshSkin* skin = model->getSkin();
  434. if (skin && skin->getRootJoint() && skin->getRootJoint()->getParent())
  435. {
  436. // For skinned meshes that have a parent node to the skin's root joint,
  437. // we need to transform the bounding volume by that parent node's transform
  438. // as well to get the full skinned bounding volume.
  439. drawDebugBox(batch, model->getMesh()->getBoundingBox(), node->getWorldMatrix() * skin->getRootJoint()->getParent()->getWorldMatrix());
  440. }
  441. else
  442. {
  443. drawDebugBox(batch, model->getMesh()->getBoundingBox(), node->getWorldMatrix());
  444. }
  445. }
  446. if (node->getTerrain())
  447. {
  448. drawDebugBox(batch, node->getTerrain()->getBoundingBox(), node->getWorldMatrix());
  449. }
  450. }
  451. if (debugFlags & Scene::DEBUG_SPHERES)
  452. {
  453. drawDebugSphere(batch, node->getBoundingSphere());
  454. }
  455. for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
  456. {
  457. drawDebugNode(scene, batch, child, debugFlags);
  458. }
  459. }
  460. void Scene::drawDebug(unsigned int debugFlags)
  461. {
  462. if (_debugBatch == NULL)
  463. {
  464. Material* material = createDebugMaterial();
  465. VertexFormat::Element elements[] =
  466. {
  467. VertexFormat::Element(VertexFormat::POSITION, 3),
  468. VertexFormat::Element(VertexFormat::COLOR, 4)
  469. };
  470. _debugBatch = MeshBatch::create(VertexFormat(elements, 2), Mesh::LINES, material, false);
  471. SAFE_RELEASE(material);
  472. }
  473. _debugBatch->start();
  474. for (Node* node = _firstNode; node != NULL; node = node->_nextSibling)
  475. {
  476. drawDebugNode(this, _debugBatch, node, debugFlags);
  477. }
  478. _debugBatch->finish();
  479. if (_activeCamera)
  480. {
  481. GP_ASSERT(_debugBatch->getMaterial());
  482. GP_ASSERT(_debugBatch->getMaterial()->getParameter("u_viewProjectionMatrix"));
  483. _debugBatch->getMaterial()->getParameter("u_viewProjectionMatrix")->setValue(_activeCamera->getViewProjectionMatrix());
  484. }
  485. _debugBatch->draw();
  486. }
  487. }