Scene.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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 Viewport& Scene::getViewport() const
  224. {
  225. return _viewport;
  226. }
  227. void Scene::setViewport(const Viewport& viewport)
  228. {
  229. _viewport = viewport;
  230. }
  231. const Vector3& Scene::getAmbientColor() const
  232. {
  233. return _ambientColor;
  234. }
  235. void Scene::setAmbientColor(float red, float green, float blue)
  236. {
  237. _ambientColor.set(red, green, blue);
  238. }
  239. Material* createDebugMaterial()
  240. {
  241. // Vertex shader for drawing colored lines.
  242. const char* vs_str =
  243. {
  244. "uniform mat4 u_viewProjectionMatrix;\n"
  245. "attribute vec4 a_position;\n"
  246. "attribute vec4 a_color;\n"
  247. "varying vec4 v_color;\n"
  248. "void main(void) {\n"
  249. " v_color = a_color;\n"
  250. " gl_Position = u_viewProjectionMatrix * a_position;\n"
  251. "}"
  252. };
  253. // Fragment shader for drawing colored lines.
  254. const char* fs_str =
  255. {
  256. #ifdef OPENGL_ES
  257. "precision highp float;\n"
  258. #endif
  259. "varying vec4 v_color;\n"
  260. "void main(void) {\n"
  261. " gl_FragColor = v_color;\n"
  262. "}"
  263. };
  264. Effect* effect = Effect::createFromSource(vs_str, fs_str);
  265. Material* material = Material::create(effect);
  266. material->getStateBlock()->setDepthTest(true);
  267. SAFE_RELEASE(effect);
  268. return material;
  269. }
  270. struct DebugVertex
  271. {
  272. float x, y, z;
  273. float r, g, b, a;
  274. };
  275. void drawDebugLine(MeshBatch* batch, const Vector3& point1, const Vector3& point2, const Vector3& color)
  276. {
  277. static DebugVertex verts[2];
  278. verts[0].x = point1.x;
  279. verts[0].y = point1.y;
  280. verts[0].z = point1.z;
  281. verts[0].r = color.x;
  282. verts[0].g = color.y;
  283. verts[0].b = color.z;
  284. verts[0].a = 1.0f;
  285. verts[1].x = point2.x;
  286. verts[1].y = point2.y;
  287. verts[1].z = point2.z;
  288. verts[1].r = color.x;
  289. verts[1].g = color.y;
  290. verts[1].b = color.z;
  291. verts[1].a = 1.0f;
  292. batch->add(verts, 2);
  293. }
  294. #define DEBUG_BOX_COLOR Vector3(0, 1, 0)
  295. #define DEBUG_SPHERE_COLOR Vector3(0, 1, 0)
  296. void drawDebugBox(MeshBatch* batch, const BoundingBox& box, const Matrix& matrix)
  297. {
  298. // Transform box into world space (since we only store local boxes on mesh)
  299. BoundingBox worldSpaceBox(box);
  300. worldSpaceBox.transform(matrix);
  301. // Get box corners
  302. static Vector3 corners[8];
  303. worldSpaceBox.getCorners(corners);
  304. // Draw box lines
  305. drawDebugLine(batch, corners[0], corners[1], DEBUG_BOX_COLOR);
  306. drawDebugLine(batch, corners[1], corners[2], DEBUG_BOX_COLOR);
  307. drawDebugLine(batch, corners[2], corners[3], DEBUG_BOX_COLOR);
  308. drawDebugLine(batch, corners[3], corners[0], DEBUG_BOX_COLOR);
  309. drawDebugLine(batch, corners[4], corners[5], DEBUG_BOX_COLOR);
  310. drawDebugLine(batch, corners[5], corners[6], DEBUG_BOX_COLOR);
  311. drawDebugLine(batch, corners[6], corners[7], DEBUG_BOX_COLOR);
  312. drawDebugLine(batch, corners[7], corners[4], DEBUG_BOX_COLOR);
  313. drawDebugLine(batch, corners[0], corners[7], DEBUG_BOX_COLOR);
  314. drawDebugLine(batch, corners[1], corners[6], DEBUG_BOX_COLOR);
  315. drawDebugLine(batch, corners[2], corners[5], DEBUG_BOX_COLOR);
  316. drawDebugLine(batch, corners[3], corners[4], DEBUG_BOX_COLOR);
  317. }
  318. void drawDebugSphere(MeshBatch* batch, const BoundingSphere& sphere)
  319. {
  320. // Draw three rings for the sphere (one for the x, y and z axes)
  321. Vector3 pos1, pos2;
  322. float step = MATH_PI * 0.2f;
  323. float max = MATH_PIX2 + step;
  324. // X ring
  325. for (float r = 0.0f; r < max; r += step)
  326. {
  327. pos2.x = sphere.center.x;
  328. pos2.y = sphere.center.y + std::cos(r) * sphere.radius;
  329. pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
  330. if (r > 0)
  331. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  332. pos1 = pos2;
  333. }
  334. // Y ring
  335. for (float r = 0.0f; r < max; r += step)
  336. {
  337. pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
  338. pos2.y = sphere.center.y;
  339. pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
  340. if (r > 0)
  341. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  342. pos1 = pos2;
  343. }
  344. // Z ring
  345. for (float r = 0.0f; r < max; r += step)
  346. {
  347. pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
  348. pos2.y = sphere.center.y + std::sin(r) * sphere.radius;
  349. pos2.z = sphere.center.z;
  350. if (r > 0)
  351. drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
  352. pos1 = pos2;
  353. }
  354. }
  355. void drawDebugNode(MeshBatch* batch, Node* node, unsigned int debugFlags)
  356. {
  357. Model* model = node->getModel();
  358. if ((debugFlags & Scene::DEBUG_BOXES) && model)
  359. {
  360. MeshSkin* skin = model->getSkin();
  361. if (skin && skin->getRootJoint()->getParent())
  362. {
  363. // For skinned meshes that have a parent node to the skin's root joint,
  364. // we need to transform the bounding volume by that parent node's transform
  365. // as well to get the full skinned bounding volume.
  366. drawDebugBox(batch, model->getMesh()->getBoundingBox(), node->getWorldMatrix() * skin->getRootJoint()->getParent()->getWorldMatrix());
  367. }
  368. else
  369. {
  370. drawDebugBox(batch, model->getMesh()->getBoundingBox(), node->getWorldMatrix());
  371. }
  372. }
  373. if ((debugFlags & Scene::DEBUG_SPHERES) && model)
  374. {
  375. drawDebugSphere(batch, node->getBoundingSphere());
  376. }
  377. Node* child = node->getFirstChild();
  378. while (child)
  379. {
  380. drawDebugNode(batch, child, debugFlags);
  381. child = child->getNextSibling();
  382. }
  383. }
  384. void Scene::drawDebug(unsigned int debugFlags)
  385. {
  386. if (_debugBatch == NULL)
  387. {
  388. Material* material = createDebugMaterial();
  389. VertexFormat::Element elements[] =
  390. {
  391. VertexFormat::Element(VertexFormat::POSITION, 3),
  392. VertexFormat::Element(VertexFormat::COLOR, 4)
  393. };
  394. _debugBatch = MeshBatch::create(VertexFormat(elements, 2), Mesh::LINES, material, false);
  395. SAFE_RELEASE(material);
  396. }
  397. _debugBatch->begin();
  398. Node* node = _firstNode;
  399. while (node)
  400. {
  401. drawDebugNode(_debugBatch, node, debugFlags);
  402. node = node->_nextSibling;
  403. }
  404. _debugBatch->end();
  405. if (_activeCamera)
  406. _debugBatch->getMaterial()->getParameter("u_viewProjectionMatrix")->setValue(_activeCamera->getViewProjectionMatrix());
  407. _debugBatch->draw();
  408. }
  409. }