123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- /****************************************************************************
- Copyright (c) 2008-2010 Ricardo Quesada
- Copyright (c) 2010-2012 cocos2d-x.org
- Copyright (c) 2011 Zynga Inc.
- Copyright (c) 2013-2016 Chukong Technologies Inc.
- Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
- http://www.cocos2d-x.org
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
- #include "2d/CCScene.h"
- #include "base/CCDirector.h"
- #include "2d/CCCamera.h"
- #include "base/CCEventDispatcher.h"
- #include "base/CCEventListenerCustom.h"
- #include "base/ccUTF8.h"
- #include "renderer/CCRenderer.h"
- #include "renderer/CCFrameBuffer.h"
- #if CC_USE_PHYSICS
- #include "physics/CCPhysicsWorld.h"
- #endif
- #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
- #include "physics3d/CCPhysics3DWorld.h"
- #include "physics3d/CCPhysics3DComponent.h"
- #endif
- #if CC_USE_NAVMESH
- #include "navmesh/CCNavMesh.h"
- #endif
- NS_CC_BEGIN
- Scene::Scene()
- {
- #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
- _physics3DWorld = nullptr;
- _physics3dDebugCamera = nullptr;
- #endif
- #if CC_USE_NAVMESH
- _navMesh = nullptr;
- _navMeshDebugCamera = nullptr;
- #endif
- #if CC_USE_PHYSICS
- _physicsWorld = nullptr;
- #endif
- _ignoreAnchorPointForPosition = true;
- setAnchorPoint(Vec2(0.5f, 0.5f));
-
- _cameraOrderDirty = true;
-
- //create default camera
- _defaultCamera = Camera::create();
- addChild(_defaultCamera);
-
- _event = Director::getInstance()->getEventDispatcher()->addCustomEventListener(Director::EVENT_PROJECTION_CHANGED, std::bind(&Scene::onProjectionChanged, this, std::placeholders::_1));
- _event->retain();
-
- Camera::_visitingCamera = nullptr;
- }
- Scene::~Scene()
- {
- #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
- CC_SAFE_RELEASE(_physics3DWorld);
- CC_SAFE_RELEASE(_physics3dDebugCamera);
- #endif
- #if CC_USE_NAVMESH
- CC_SAFE_RELEASE(_navMesh);
- #endif
- Director::getInstance()->getEventDispatcher()->removeEventListener(_event);
- CC_SAFE_RELEASE(_event);
-
- #if CC_USE_PHYSICS
- delete _physicsWorld;
- #endif
-
- #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
- auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
- if (sEngine)
- {
- sEngine->releaseAllChildrenRecursive(this);
- }
- #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
- }
- #if CC_USE_NAVMESH
- void Scene::setNavMesh(NavMesh* navMesh)
- {
- if (_navMesh != navMesh)
- {
- CC_SAFE_RETAIN(navMesh);
- CC_SAFE_RELEASE(_navMesh);
- _navMesh = navMesh;
- }
- }
- #endif
- bool Scene::init()
- {
- auto size = Director::getInstance()->getWinSize();
- return initWithSize(size);
- }
- bool Scene::initWithSize(const Size& size)
- {
- setContentSize(size);
- return true;
- }
- Scene* Scene::create()
- {
- Scene *ret = new (std::nothrow) Scene();
- if (ret && ret->init())
- {
- ret->autorelease();
- return ret;
- }
- else
- {
- CC_SAFE_DELETE(ret);
- return nullptr;
- }
- }
- Scene* Scene::createWithSize(const Size& size)
- {
- Scene *ret = new (std::nothrow) Scene();
- if (ret && ret->initWithSize(size))
- {
- ret->autorelease();
- return ret;
- }
- else
- {
- CC_SAFE_DELETE(ret);
- return nullptr;
- }
- }
- std::string Scene::getDescription() const
- {
- return StringUtils::format("<Scene | tag = %d>", _tag);
- }
- void Scene::onProjectionChanged(EventCustom* /*event*/)
- {
- if (_defaultCamera)
- {
- _defaultCamera->initDefault();
- }
- }
- static bool camera_cmp(const Camera* a, const Camera* b)
- {
- return a->getRenderOrder() < b->getRenderOrder();
- }
- const std::vector<Camera*>& Scene::getCameras()
- {
- if (_cameraOrderDirty)
- {
- stable_sort(_cameras.begin(), _cameras.end(), camera_cmp);
- _cameraOrderDirty = false;
- }
- return _cameras;
- }
- void Scene::render(Renderer* renderer, const Mat4& eyeTransform, const Mat4* eyeProjection)
- {
- render(renderer, &eyeTransform, eyeProjection, 1);
- }
- void Scene::render(Renderer* renderer, const Mat4* eyeTransforms, const Mat4* eyeProjections, unsigned int multiViewCount)
- {
- auto director = Director::getInstance();
- Camera* defaultCamera = nullptr;
- const auto& transform = getNodeToParentTransform();
- for (const auto& camera : getCameras())
- {
- if (!camera->isVisible())
- continue;
- Camera::_visitingCamera = camera;
- if (Camera::_visitingCamera->getCameraFlag() == CameraFlag::DEFAULT)
- {
- defaultCamera = Camera::_visitingCamera;
- }
- // There are two ways to modify the "default camera" with the eye Transform:
- // a) modify the "nodeToParentTransform" matrix
- // b) modify the "additional transform" matrix
- // both alternatives are correct, if the user manually modifies the camera with a camera->setPosition()
- // then the "nodeToParent transform" will be lost.
- // And it is important that the change is "permanent", because the matrix might be used for calculate
- // culling and other stuff.
- for (unsigned int i = 0; i < multiViewCount; ++i) {
- if (eyeProjections)
- camera->setAdditionalProjection(eyeProjections[i] * camera->getProjectionMatrix().getInversed());
- if (eyeTransforms)
- camera->setAdditionalTransform(eyeTransforms[i].getInversed());
- director->pushProjectionMatrix(i);
- director->loadProjectionMatrix(Camera::_visitingCamera->getViewProjectionMatrix(), i);
- }
- camera->apply();
- //clear background with max depth
- camera->clearBackground();
- //visit the scene
- visit(renderer, transform, 0);
- #if CC_USE_NAVMESH
- if (_navMesh && _navMeshDebugCamera == camera)
- {
- _navMesh->debugDraw(renderer);
- }
- #endif
- renderer->render();
- camera->restore();
- for (unsigned int i = 0; i < multiViewCount; ++i)
- director->popProjectionMatrix(i);
- // we shouldn't restore the transform matrix since it could be used
- // from "update" or other parts of the game to calculate culling or something else.
- // camera->setNodeToParentTransform(eyeCopy);
- }
- #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
- if (_physics3DWorld && _physics3DWorld->isDebugDrawEnabled())
- {
- Camera *physics3dDebugCamera = _physics3dDebugCamera != nullptr ? _physics3dDebugCamera: defaultCamera;
-
- for (unsigned int i = 0; i < multiViewCount; ++i) {
- if (eyeProjections)
- physics3dDebugCamera->setAdditionalProjection(eyeProjections[i] * physics3dDebugCamera->getProjectionMatrix().getInversed());
- if (eyeTransforms)
- physics3dDebugCamera->setAdditionalTransform(eyeTransforms[i].getInversed());
- director->pushProjectionMatrix(i);
- director->loadProjectionMatrix(physics3dDebugCamera->getViewProjectionMatrix(), i);
- }
-
- physics3dDebugCamera->apply();
- physics3dDebugCamera->clearBackground();
- _physics3DWorld->debugDraw(renderer);
- renderer->render();
-
- physics3dDebugCamera->restore();
- for (unsigned int i = 0; i < multiViewCount; ++i)
- director->popProjectionMatrix(i);
- }
- #endif
- Camera::_visitingCamera = nullptr;
- // experimental::FrameBuffer::applyDefaultFBO();
- }
- void Scene::removeAllChildren()
- {
- if (_defaultCamera)
- _defaultCamera->retain();
- Node::removeAllChildren();
- if (_defaultCamera)
- {
- addChild(_defaultCamera);
- _defaultCamera->release();
- }
- }
- #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
- void Scene::setPhysics3DDebugCamera(Camera* camera)
- {
- CC_SAFE_RETAIN(camera);
- CC_SAFE_RELEASE(_physics3dDebugCamera);
- _physics3dDebugCamera = camera;
- }
- #endif
- #if CC_USE_NAVMESH
- void Scene::setNavMeshDebugCamera(Camera *camera)
- {
- CC_SAFE_RETAIN(camera);
- CC_SAFE_RELEASE(_navMeshDebugCamera);
- _navMeshDebugCamera = camera;
- }
- #endif
- #if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION))
- Scene* Scene::createWithPhysics()
- {
- Scene *ret = new (std::nothrow) Scene();
- if (ret && ret->initWithPhysics())
- {
- ret->autorelease();
- return ret;
- }
- else
- {
- CC_SAFE_DELETE(ret);
- return nullptr;
- }
- }
- bool Scene::initWithPhysics()
- {
- #if CC_USE_PHYSICS
- _physicsWorld = PhysicsWorld::construct(this);
- #endif
- bool ret = false;
- do
- {
- Director * director;
- CC_BREAK_IF( ! (director = Director::getInstance()) );
- this->setContentSize(director->getWinSize());
- #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
- Physics3DWorldDes info;
- CC_BREAK_IF(! (_physics3DWorld = Physics3DWorld::create(&info)));
- _physics3DWorld->retain();
- #endif
- // success
- ret = true;
- } while (0);
- return ret;
- }
- #endif
- #if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)
- void Scene::stepPhysicsAndNavigation(float deltaTime)
- {
- #if CC_USE_PHYSICS
- if (_physicsWorld && _physicsWorld->isAutoStep())
- _physicsWorld->update(deltaTime);
- #endif
- #if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
- if (_physics3DWorld)
- {
- _physics3DWorld->stepSimulate(deltaTime);
- }
- #endif
- #if CC_USE_NAVMESH
- if (_navMesh)
- {
- _navMesh->update(deltaTime);
- }
- #endif
- }
- #endif
- NS_CC_END
|