fix default camera, add listener for projection change

This commit is contained in:
yangxiao 2014-08-12 14:42:08 +08:00
Родитель e0ef4d16d3
Коммит 32645c1622
4 изменённых файлов: 106 добавлений и 32 удалений

Просмотреть файл

@ -28,6 +28,8 @@ THE SOFTWARE.
#include "2d/CCScene.h"
#include "base/CCDirector.h"
#include "base/CCCamera.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventListenerCustom.h"
#include "2d/CCLayer.h"
#include "2d/CCSprite.h"
#include "2d/CCSpriteBatchNode.h"
@ -43,6 +45,8 @@ Scene::Scene()
{
_ignoreAnchorPointForPosition = true;
setAnchorPoint(Vec2(0.5f, 0.5f));
_event = nullptr;
_defaultCamera = nullptr;
}
Scene::~Scene()
@ -50,6 +54,8 @@ Scene::~Scene()
#if CC_USE_PHYSICS
CC_SAFE_DELETE(_physicsWorld);
#endif
Director::getInstance()->getEventDispatcher()->removeEventListener(_event);
CC_SAFE_RELEASE(_event);
}
bool Scene::init()
@ -61,8 +67,14 @@ bool Scene::init()
bool Scene::initWithSize(const Size& size)
{
//create default camera
auto camera = Camera::create();
addChild(camera);
_defaultCamera = Camera::create();
addChild(_defaultCamera);
CCLOG("camera %p", _defaultCamera);
_event = Director::getInstance()->getEventDispatcher()->addCustomEventListener(Director::EVENT_PROJECTION_CHANGED, std::bind(&Scene::onProjectionChanged, this, std::placeholders::_1));
_event->retain();
static int tag = 0;
setTag(tag++);
setContentSize(size);
return true;
@ -154,8 +166,10 @@ bool Scene::initWithPhysics()
Director * director;
CC_BREAK_IF( ! (director = Director::getInstance()) );
// add camera
auto camera = Camera::create();
addChild(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();
this->setContentSize(director->getWinSize());
CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::construct(*this)));
@ -189,6 +203,14 @@ void Scene::addChildToPhysicsWorld(Node* child)
}
}
void Scene::onProjectionChanged(EventCustom* event)
{
if (_defaultCamera)
{
_defaultCamera->initDefault();
}
}
#endif
NS_CC_END

Просмотреть файл

@ -75,6 +75,8 @@ CC_CONSTRUCTOR_ACCESS:
bool init();
bool initWithSize(const Size& size);
void onProjectionChanged(EventCustom* event);
protected:
friend class Node;
friend class ProtectedNode;
@ -83,6 +85,8 @@ protected:
friend class Director;
std::vector<Camera*> _cameras; //weak ref to Camera
Camera* _defaultCamera; //weak ref, default camera created by scene, _cameras[0], Caution that the default camera can not be added to _cameras before onEnter is called
EventListenerCustom* _event;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Scene);

Просмотреть файл

@ -65,20 +65,7 @@ Camera* Camera::createPerspective(float fieldOfView, float aspectRatio, float ne
auto ret = new Camera();
if (ret)
{
ret->_fieldOfView = fieldOfView;
ret->_aspectRatio = aspectRatio;
ret->_nearPlane = nearPlane;
ret->_farPlane = farPlane;
Mat4::createPerspective(ret->_fieldOfView, ret->_aspectRatio, ret->_nearPlane, ret->_farPlane, &ret->_projection);
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
//if needed, we need to add a rotation for Landscape orientations on Windows Phone 8 since it is always in Portrait Mode
GLView* view = Director::getInstance()->getOpenGLView();
if(view != nullptr)
{
setAdditionalProjection(view->getOrientationMatrix());
}
#endif
ret->_viewProjectionDirty = true;
ret->initPerspective(fieldOfView, aspectRatio, nearPlane, farPlane);
ret->autorelease();
return ret;
}
@ -91,20 +78,7 @@ Camera* Camera::createOrthographic(float zoomX, float zoomY, float nearPlane, fl
auto ret = new Camera();
if (ret)
{
ret->_zoom[0] = zoomX;
ret->_zoom[1] = zoomY;
ret->_nearPlane = nearPlane;
ret->_farPlane = farPlane;
Mat4::createOrthographic(ret->_zoom[0], ret->_zoom[1], ret->_nearPlane, ret->_farPlane, &ret->_projection);
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
//if needed, we need to add a rotation for Landscape orientations on Windows Phone 8 since it is always in Portrait Mode
GLView* view = Director::getInstance()->getOpenGLView();
if(view != nullptr)
{
setAdditionalProjection(view->getOrientationMatrix());
}
#endif
ret->_viewProjectionDirty = true;
ret->initOrthographic(zoomX, zoomY, nearPlane, farPlane);
ret->autorelease();
return ret;
}
@ -203,6 +177,74 @@ void Camera::setAdditionalProjection(const Mat4& mat)
getViewProjectionMatrix();
}
bool Camera::initDefault()
{
auto size = Director::getInstance()->getWinSize();
//create default camera
auto projection = Director::getInstance()->getProjection();
switch (projection)
{
case Director::Projection::_2D:
{
initOrthographic(size.width, size.height, -1024, 1024);
break;
}
case Director::Projection::_3D:
{
float zeye = Director::getInstance()->getZEye();
initPerspective(60, (GLfloat)size.width / size.height, 10, zeye + size.height / 2.0f);
Vec3 eye(size.width/2, size.height/2.0f, zeye), center(size.width/2, size.height/2, 0.0f), up(0.0f, 1.0f, 0.0f);
setPosition3D(eye);
lookAt(center, up);
break;
}
default:
CCLOG("unrecognized projection");
break;
}
return true;
}
bool Camera::initPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
{
_fieldOfView = fieldOfView;
_aspectRatio = aspectRatio;
_nearPlane = nearPlane;
_farPlane = farPlane;
Mat4::createPerspective(_fieldOfView, _aspectRatio, _nearPlane, _farPlane, &_projection);
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
//if needed, we need to add a rotation for Landscape orientations on Windows Phone 8 since it is always in Portrait Mode
GLView* view = Director::getInstance()->getOpenGLView();
if(view != nullptr)
{
setAdditionalProjection(view->getOrientationMatrix());
}
#endif
_viewProjectionDirty = true;
return true;
}
bool Camera::initOrthographic(float zoomX, float zoomY, float nearPlane, float farPlane)
{
_zoom[0] = zoomX;
_zoom[1] = zoomY;
_nearPlane = nearPlane;
_farPlane = farPlane;
Mat4::createOrthographic(_zoom[0], _zoom[1], _nearPlane, _farPlane, &_projection);
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
//if needed, we need to add a rotation for Landscape orientations on Windows Phone 8 since it is always in Portrait Mode
GLView* view = Director::getInstance()->getOpenGLView();
if(view != nullptr)
{
setAdditionalProjection(view->getOrientationMatrix());
}
#endif
_viewProjectionDirty = true;
return true;
}
void Camera::unproject(const Size& viewport, Vec3* src, Vec3* dst) const
{
assert(dst);

Просмотреть файл

@ -50,6 +50,7 @@ enum class CameraFlag
*/
class CC_DLL Camera :public Node
{
friend class Scene;
public:
/**
* The type of camera.
@ -143,6 +144,11 @@ CC_CONSTRUCTOR_ACCESS:
/**set additional matrix for the projection matrix, it multiplys mat to projection matrix when called, used by WP8*/
void setAdditionalProjection(const Mat4& mat);
/** init camera */
bool initDefault();
bool initPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane);
bool initOrthographic(float zoomX, float zoomY, float nearPlane, float farPlane);
protected:
Scene* _scene; //Scene camera belongs to