CCScene.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /****************************************************************************
  2. Copyright (c) 2008-2010 Ricardo Quesada
  3. Copyright (c) 2010-2012 cocos2d-x.org
  4. Copyright (c) 2011 Zynga Inc.
  5. Copyright (c) 2013-2016 Chukong Technologies Inc.
  6. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
  7. http://www.cocos2d-x.org
  8. Permission is hereby granted, free of charge, to any person obtaining a copy
  9. of this software and associated documentation files (the "Software"), to deal
  10. in the Software without restriction, including without limitation the rights
  11. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. copies of the Software, and to permit persons to whom the Software is
  13. furnished to do so, subject to the following conditions:
  14. The above copyright notice and this permission notice shall be included in
  15. all copies or substantial portions of the Software.
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. THE SOFTWARE.
  23. ****************************************************************************/
  24. #include "2d/CCScene.h"
  25. #include "base/CCDirector.h"
  26. #include "2d/CCCamera.h"
  27. #include "base/CCEventDispatcher.h"
  28. #include "base/CCEventListenerCustom.h"
  29. #include "base/ccUTF8.h"
  30. #include "renderer/CCRenderer.h"
  31. #include "renderer/CCFrameBuffer.h"
  32. #if CC_USE_PHYSICS
  33. #include "physics/CCPhysicsWorld.h"
  34. #endif
  35. #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
  36. #include "physics3d/CCPhysics3DWorld.h"
  37. #include "physics3d/CCPhysics3DComponent.h"
  38. #endif
  39. #if CC_USE_NAVMESH
  40. #include "navmesh/CCNavMesh.h"
  41. #endif
  42. NS_CC_BEGIN
  43. Scene::Scene()
  44. {
  45. #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
  46. _physics3DWorld = nullptr;
  47. _physics3dDebugCamera = nullptr;
  48. #endif
  49. #if CC_USE_NAVMESH
  50. _navMesh = nullptr;
  51. _navMeshDebugCamera = nullptr;
  52. #endif
  53. #if CC_USE_PHYSICS
  54. _physicsWorld = nullptr;
  55. #endif
  56. _ignoreAnchorPointForPosition = true;
  57. setAnchorPoint(Vec2(0.5f, 0.5f));
  58. _cameraOrderDirty = true;
  59. //create default camera
  60. _defaultCamera = Camera::create();
  61. addChild(_defaultCamera);
  62. _event = Director::getInstance()->getEventDispatcher()->addCustomEventListener(Director::EVENT_PROJECTION_CHANGED, std::bind(&Scene::onProjectionChanged, this, std::placeholders::_1));
  63. _event->retain();
  64. Camera::_visitingCamera = nullptr;
  65. }
  66. Scene::~Scene()
  67. {
  68. #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
  69. CC_SAFE_RELEASE(_physics3DWorld);
  70. CC_SAFE_RELEASE(_physics3dDebugCamera);
  71. #endif
  72. #if CC_USE_NAVMESH
  73. CC_SAFE_RELEASE(_navMesh);
  74. #endif
  75. Director::getInstance()->getEventDispatcher()->removeEventListener(_event);
  76. CC_SAFE_RELEASE(_event);
  77. #if CC_USE_PHYSICS
  78. delete _physicsWorld;
  79. #endif
  80. #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  81. auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
  82. if (sEngine)
  83. {
  84. sEngine->releaseAllChildrenRecursive(this);
  85. }
  86. #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  87. }
  88. #if CC_USE_NAVMESH
  89. void Scene::setNavMesh(NavMesh* navMesh)
  90. {
  91. if (_navMesh != navMesh)
  92. {
  93. CC_SAFE_RETAIN(navMesh);
  94. CC_SAFE_RELEASE(_navMesh);
  95. _navMesh = navMesh;
  96. }
  97. }
  98. #endif
  99. bool Scene::init()
  100. {
  101. auto size = Director::getInstance()->getWinSize();
  102. return initWithSize(size);
  103. }
  104. bool Scene::initWithSize(const Size& size)
  105. {
  106. setContentSize(size);
  107. return true;
  108. }
  109. Scene* Scene::create()
  110. {
  111. Scene *ret = new (std::nothrow) Scene();
  112. if (ret && ret->init())
  113. {
  114. ret->autorelease();
  115. return ret;
  116. }
  117. else
  118. {
  119. CC_SAFE_DELETE(ret);
  120. return nullptr;
  121. }
  122. }
  123. Scene* Scene::createWithSize(const Size& size)
  124. {
  125. Scene *ret = new (std::nothrow) Scene();
  126. if (ret && ret->initWithSize(size))
  127. {
  128. ret->autorelease();
  129. return ret;
  130. }
  131. else
  132. {
  133. CC_SAFE_DELETE(ret);
  134. return nullptr;
  135. }
  136. }
  137. std::string Scene::getDescription() const
  138. {
  139. return StringUtils::format("<Scene | tag = %d>", _tag);
  140. }
  141. void Scene::onProjectionChanged(EventCustom* /*event*/)
  142. {
  143. if (_defaultCamera)
  144. {
  145. _defaultCamera->initDefault();
  146. }
  147. }
  148. static bool camera_cmp(const Camera* a, const Camera* b)
  149. {
  150. return a->getRenderOrder() < b->getRenderOrder();
  151. }
  152. const std::vector<Camera*>& Scene::getCameras()
  153. {
  154. if (_cameraOrderDirty)
  155. {
  156. stable_sort(_cameras.begin(), _cameras.end(), camera_cmp);
  157. _cameraOrderDirty = false;
  158. }
  159. return _cameras;
  160. }
  161. void Scene::render(Renderer* renderer, const Mat4& eyeTransform, const Mat4* eyeProjection)
  162. {
  163. render(renderer, &eyeTransform, eyeProjection, 1);
  164. }
  165. void Scene::render(Renderer* renderer, const Mat4* eyeTransforms, const Mat4* eyeProjections, unsigned int multiViewCount)
  166. {
  167. auto director = Director::getInstance();
  168. Camera* defaultCamera = nullptr;
  169. const auto& transform = getNodeToParentTransform();
  170. for (const auto& camera : getCameras())
  171. {
  172. if (!camera->isVisible())
  173. continue;
  174. Camera::_visitingCamera = camera;
  175. if (Camera::_visitingCamera->getCameraFlag() == CameraFlag::DEFAULT)
  176. {
  177. defaultCamera = Camera::_visitingCamera;
  178. }
  179. // There are two ways to modify the "default camera" with the eye Transform:
  180. // a) modify the "nodeToParentTransform" matrix
  181. // b) modify the "additional transform" matrix
  182. // both alternatives are correct, if the user manually modifies the camera with a camera->setPosition()
  183. // then the "nodeToParent transform" will be lost.
  184. // And it is important that the change is "permanent", because the matrix might be used for calculate
  185. // culling and other stuff.
  186. for (unsigned int i = 0; i < multiViewCount; ++i) {
  187. if (eyeProjections)
  188. camera->setAdditionalProjection(eyeProjections[i] * camera->getProjectionMatrix().getInversed());
  189. if (eyeTransforms)
  190. camera->setAdditionalTransform(eyeTransforms[i].getInversed());
  191. director->pushProjectionMatrix(i);
  192. director->loadProjectionMatrix(Camera::_visitingCamera->getViewProjectionMatrix(), i);
  193. }
  194. camera->apply();
  195. //clear background with max depth
  196. camera->clearBackground();
  197. //visit the scene
  198. visit(renderer, transform, 0);
  199. #if CC_USE_NAVMESH
  200. if (_navMesh && _navMeshDebugCamera == camera)
  201. {
  202. _navMesh->debugDraw(renderer);
  203. }
  204. #endif
  205. renderer->render();
  206. camera->restore();
  207. for (unsigned int i = 0; i < multiViewCount; ++i)
  208. director->popProjectionMatrix(i);
  209. // we shouldn't restore the transform matrix since it could be used
  210. // from "update" or other parts of the game to calculate culling or something else.
  211. // camera->setNodeToParentTransform(eyeCopy);
  212. }
  213. #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
  214. if (_physics3DWorld && _physics3DWorld->isDebugDrawEnabled())
  215. {
  216. Camera *physics3dDebugCamera = _physics3dDebugCamera != nullptr ? _physics3dDebugCamera: defaultCamera;
  217. for (unsigned int i = 0; i < multiViewCount; ++i) {
  218. if (eyeProjections)
  219. physics3dDebugCamera->setAdditionalProjection(eyeProjections[i] * physics3dDebugCamera->getProjectionMatrix().getInversed());
  220. if (eyeTransforms)
  221. physics3dDebugCamera->setAdditionalTransform(eyeTransforms[i].getInversed());
  222. director->pushProjectionMatrix(i);
  223. director->loadProjectionMatrix(physics3dDebugCamera->getViewProjectionMatrix(), i);
  224. }
  225. physics3dDebugCamera->apply();
  226. physics3dDebugCamera->clearBackground();
  227. _physics3DWorld->debugDraw(renderer);
  228. renderer->render();
  229. physics3dDebugCamera->restore();
  230. for (unsigned int i = 0; i < multiViewCount; ++i)
  231. director->popProjectionMatrix(i);
  232. }
  233. #endif
  234. Camera::_visitingCamera = nullptr;
  235. // experimental::FrameBuffer::applyDefaultFBO();
  236. }
  237. void Scene::removeAllChildren()
  238. {
  239. if (_defaultCamera)
  240. _defaultCamera->retain();
  241. Node::removeAllChildren();
  242. if (_defaultCamera)
  243. {
  244. addChild(_defaultCamera);
  245. _defaultCamera->release();
  246. }
  247. }
  248. #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
  249. void Scene::setPhysics3DDebugCamera(Camera* camera)
  250. {
  251. CC_SAFE_RETAIN(camera);
  252. CC_SAFE_RELEASE(_physics3dDebugCamera);
  253. _physics3dDebugCamera = camera;
  254. }
  255. #endif
  256. #if CC_USE_NAVMESH
  257. void Scene::setNavMeshDebugCamera(Camera *camera)
  258. {
  259. CC_SAFE_RETAIN(camera);
  260. CC_SAFE_RELEASE(_navMeshDebugCamera);
  261. _navMeshDebugCamera = camera;
  262. }
  263. #endif
  264. #if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION))
  265. Scene* Scene::createWithPhysics()
  266. {
  267. Scene *ret = new (std::nothrow) Scene();
  268. if (ret && ret->initWithPhysics())
  269. {
  270. ret->autorelease();
  271. return ret;
  272. }
  273. else
  274. {
  275. CC_SAFE_DELETE(ret);
  276. return nullptr;
  277. }
  278. }
  279. bool Scene::initWithPhysics()
  280. {
  281. #if CC_USE_PHYSICS
  282. _physicsWorld = PhysicsWorld::construct(this);
  283. #endif
  284. bool ret = false;
  285. do
  286. {
  287. Director * director;
  288. CC_BREAK_IF( ! (director = Director::getInstance()) );
  289. this->setContentSize(director->getWinSize());
  290. #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
  291. Physics3DWorldDes info;
  292. CC_BREAK_IF(! (_physics3DWorld = Physics3DWorld::create(&info)));
  293. _physics3DWorld->retain();
  294. #endif
  295. // success
  296. ret = true;
  297. } while (0);
  298. return ret;
  299. }
  300. #endif
  301. #if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)
  302. void Scene::stepPhysicsAndNavigation(float deltaTime)
  303. {
  304. #if CC_USE_PHYSICS
  305. if (_physicsWorld && _physicsWorld->isAutoStep())
  306. _physicsWorld->update(deltaTime);
  307. #endif
  308. #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
  309. if (_physics3DWorld)
  310. {
  311. _physics3DWorld->stepSimulate(deltaTime);
  312. }
  313. #endif
  314. #if CC_USE_NAVMESH
  315. if (_navMesh)
  316. {
  317. _navMesh->update(deltaTime);
  318. }
  319. #endif
  320. }
  321. #endif
  322. NS_CC_END