Scene.cpp 12 KB

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