2
0

Scene.cpp 13 KB

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