Scene.cpp 13 KB

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