mirror of https://github.com/axmolengine/axmol.git
Add zoom and camera features.
This commit is contained in:
parent
d6bfe25f76
commit
6d5c1a446a
|
@ -94,6 +94,12 @@ const Camera* Camera::getVisitingCamera()
|
||||||
// end static methods
|
// end static methods
|
||||||
|
|
||||||
Camera::Camera()
|
Camera::Camera()
|
||||||
|
: _eyeZdistance(1)
|
||||||
|
, _zoomFactor(1)
|
||||||
|
, _nearPlane(-1024)
|
||||||
|
, _farPlane(1024)
|
||||||
|
, _zoomFactorFarPlane(1024)
|
||||||
|
, _positionCenter({0, 0})
|
||||||
{
|
{
|
||||||
// minggo comment
|
// minggo comment
|
||||||
// _frustum.setClipZ(true);
|
// _frustum.setClipZ(true);
|
||||||
|
@ -137,6 +143,7 @@ void Camera::lookAt(const Vec3& lookAtPos, const Vec3& up)
|
||||||
Vec3::cross(zaxis, xaxis, &yaxis);
|
Vec3::cross(zaxis, xaxis, &yaxis);
|
||||||
yaxis.normalize();
|
yaxis.normalize();
|
||||||
Mat4 rotation;
|
Mat4 rotation;
|
||||||
|
|
||||||
rotation.m[0] = xaxis.x;
|
rotation.m[0] = xaxis.x;
|
||||||
rotation.m[1] = xaxis.y;
|
rotation.m[1] = xaxis.y;
|
||||||
rotation.m[2] = xaxis.z;
|
rotation.m[2] = xaxis.z;
|
||||||
|
@ -146,6 +153,7 @@ void Camera::lookAt(const Vec3& lookAtPos, const Vec3& up)
|
||||||
rotation.m[5] = yaxis.y;
|
rotation.m[5] = yaxis.y;
|
||||||
rotation.m[6] = yaxis.z;
|
rotation.m[6] = yaxis.z;
|
||||||
rotation.m[7] = 0;
|
rotation.m[7] = 0;
|
||||||
|
|
||||||
rotation.m[8] = zaxis.x;
|
rotation.m[8] = zaxis.x;
|
||||||
rotation.m[9] = zaxis.y;
|
rotation.m[9] = zaxis.y;
|
||||||
rotation.m[10] = zaxis.z;
|
rotation.m[10] = zaxis.z;
|
||||||
|
@ -177,6 +185,8 @@ void Camera::setAdditionalProjection(const Mat4& mat)
|
||||||
|
|
||||||
bool Camera::initDefault()
|
bool Camera::initDefault()
|
||||||
{
|
{
|
||||||
|
_projectionType = Director::getInstance()->getProjection();
|
||||||
|
|
||||||
auto size = _director->getWinSize();
|
auto size = _director->getWinSize();
|
||||||
// create default camera
|
// create default camera
|
||||||
auto projection = _director->getProjection();
|
auto projection = _director->getProjection();
|
||||||
|
@ -185,7 +195,7 @@ bool Camera::initDefault()
|
||||||
case Director::Projection::_2D:
|
case Director::Projection::_2D:
|
||||||
{
|
{
|
||||||
initOrthographic(size.width, size.height, -1024, 1024);
|
initOrthographic(size.width, size.height, -1024, 1024);
|
||||||
setPosition3D(Vec3(0.0f, 0.0f, 0.0f));
|
setPosition3D(Vec3(0.f, 0.f, 0.f));
|
||||||
setRotation3D(Vec3(0.f, 0.f, 0.f));
|
setRotation3D(Vec3(0.f, 0.f, 0.f));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +205,7 @@ bool Camera::initDefault()
|
||||||
initPerspective(60, (float)size.width / size.height, 10, zeye + size.height / 2.0f);
|
initPerspective(60, (float)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),
|
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);
|
up(0.0f, 1.0f, 0.0f);
|
||||||
|
_eyeZdistance = eye.z;
|
||||||
setPosition3D(eye);
|
setPosition3D(eye);
|
||||||
lookAt(center, up);
|
lookAt(center, up);
|
||||||
break;
|
break;
|
||||||
|
@ -203,15 +214,19 @@ bool Camera::initDefault()
|
||||||
CCLOG("unrecognized projection");
|
CCLOG("unrecognized projection");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (_zoomFactor != 1.0F)
|
||||||
|
applyZoom();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::initPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
|
bool Camera::initPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
|
||||||
{
|
{
|
||||||
_fieldOfView = fieldOfView;
|
_fieldOfView = fieldOfView;
|
||||||
_aspectRatio = aspectRatio;
|
_aspectRatio = aspectRatio;
|
||||||
_nearPlane = nearPlane;
|
_nearPlane = nearPlane;
|
||||||
_farPlane = farPlane;
|
_farPlane = farPlane;
|
||||||
|
if (_zoomFactorFarPlane == 1024)
|
||||||
|
_zoomFactorFarPlane = farPlane;
|
||||||
Mat4::createPerspective(_fieldOfView, _aspectRatio, _nearPlane, _farPlane, &_projection);
|
Mat4::createPerspective(_fieldOfView, _aspectRatio, _nearPlane, _farPlane, &_projection);
|
||||||
_viewProjectionDirty = true;
|
_viewProjectionDirty = true;
|
||||||
_frustumDirty = true;
|
_frustumDirty = true;
|
||||||
|
@ -354,6 +369,82 @@ void Camera::setDepth(int8_t depth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::setZoom(float factor)
|
||||||
|
{
|
||||||
|
// Stretch the far plane further the more we zoom out.
|
||||||
|
if (_projectionType == Director::Projection::_3D && _zoomFactorFarPlane * factor > _farPlane)
|
||||||
|
{
|
||||||
|
_farPlane = _zoomFactorFarPlane * factor;
|
||||||
|
applyCustomProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
_zoomFactor = factor;
|
||||||
|
applyZoom();
|
||||||
|
if (_projectionType == Director::Projection::_2D)
|
||||||
|
setPositionCenter(_positionCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::setPositionCenter(const Vec2& position)
|
||||||
|
{
|
||||||
|
setPositionCenter(position.x, position.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::setPositionCenter(float x, float y)
|
||||||
|
{
|
||||||
|
Vec2 pos = {x, y};
|
||||||
|
_positionCenter = pos;
|
||||||
|
auto v = Director::getInstance()->getVisibleSize();
|
||||||
|
setPosition(pos.x + v.width / 2 * (1.0F - _zoomFactor), pos.y + v.height / 2 * (1.0F - _zoomFactor));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyZoom()
|
||||||
|
{
|
||||||
|
switch (_projectionType)
|
||||||
|
{
|
||||||
|
case cocos2d::Director::Projection::_2D:
|
||||||
|
{
|
||||||
|
this->setScale(_zoomFactor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case cocos2d::Director::Projection::_3D:
|
||||||
|
{
|
||||||
|
this->setPositionZ(_eyeZdistance * _zoomFactor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyCustomProperties()
|
||||||
|
{
|
||||||
|
_projectionType = Director::getInstance()->getProjection();
|
||||||
|
|
||||||
|
auto& size = _director->getWinSize();
|
||||||
|
// create default camera
|
||||||
|
switch (_projectionType)
|
||||||
|
{
|
||||||
|
case Director::Projection::_2D:
|
||||||
|
{
|
||||||
|
initOrthographic(size.width, size.height, _nearPlane, _farPlane);
|
||||||
|
setPosition3D(Vec3(0.f, 0.f, 0.f));
|
||||||
|
setRotation3D(Vec3(0.f, 0.f, 0.f));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Director::Projection::_3D:
|
||||||
|
{
|
||||||
|
float zeye = _director->getZEye();
|
||||||
|
initPerspective(_fieldOfView, _aspectRatio, _nearPlane, _farPlane);
|
||||||
|
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);
|
||||||
|
_eyeZdistance = eye.z;
|
||||||
|
setPosition3D(eye);
|
||||||
|
lookAt(center, up);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_zoomFactor != 1.0F)
|
||||||
|
applyZoom();
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::onEnter()
|
void Camera::onEnter()
|
||||||
{
|
{
|
||||||
if (_scene == nullptr)
|
if (_scene == nullptr)
|
||||||
|
@ -431,6 +522,30 @@ int Camera::getRenderOrder() const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::setAspectRatio(float ratio)
|
||||||
|
{
|
||||||
|
_aspectRatio = ratio;
|
||||||
|
applyCustomProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::setFOV(float fieldOfView)
|
||||||
|
{
|
||||||
|
_fieldOfView = fieldOfView;
|
||||||
|
applyCustomProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::setFarPlane(float farPlane)
|
||||||
|
{
|
||||||
|
_farPlane = farPlane;
|
||||||
|
applyCustomProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::setNearPlane(float nearPlane)
|
||||||
|
{
|
||||||
|
_nearPlane = nearPlane;
|
||||||
|
applyCustomProperties();
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::visit(Renderer* renderer, const Mat4& parentTransform, uint32_t parentFlags)
|
void Camera::visit(Renderer* renderer, const Mat4& parentTransform, uint32_t parentFlags)
|
||||||
{
|
{
|
||||||
_viewProjectionUpdated = _transformUpdated;
|
_viewProjectionUpdated = _transformUpdated;
|
||||||
|
|
|
@ -234,22 +234,94 @@ public:
|
||||||
int getRenderOrder() const;
|
int getRenderOrder() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the frustum's far plane.
|
* Gets the aspect ratio of the camera if the projection mode is 3D.
|
||||||
|
*/
|
||||||
|
float getAspectRatio() const { return _fieldOfView; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the aspect ratio of the camera if the projection mode is 3D.
|
||||||
|
*/
|
||||||
|
void setAspectRatio(float ratio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the field of view of the camera if the projection mode is 3D.
|
||||||
|
*/
|
||||||
|
float getFOV() const { return _fieldOfView; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the field of view of the camera if the projection mode is 3D.
|
||||||
|
*/
|
||||||
|
void setFOV(float fov);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the frustum's far plane.
|
||||||
*/
|
*/
|
||||||
float getFarPlane() const { return _farPlane; }
|
float getFarPlane() const { return _farPlane; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the frustum's near plane.
|
* Sets the frustum's far plane.
|
||||||
|
*/
|
||||||
|
void setFarPlane(float farPlane);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the frustum's near plane.
|
||||||
*/
|
*/
|
||||||
float getNearPlane() const { return _nearPlane; }
|
float getNearPlane() const { return _nearPlane; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the frustum's near plane.
|
||||||
|
*/
|
||||||
|
void setNearPlane(float nearPlane);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the zoom multiplier of the camera.
|
||||||
|
*/
|
||||||
|
float getZoom() const { return _zoomFactor; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the zoom multiplier of the camera.
|
||||||
|
* This is designed to be used with 2D views only.
|
||||||
|
*
|
||||||
|
* For 2D projection mode the zoom will be at the bottom left of the viewport, If you don't want this behaviour and
|
||||||
|
* want it to be around the center then you need to use the functions 'setPositionCenter()' and 'getPositionCenter()'
|
||||||
|
*
|
||||||
|
* @param factor The zoom factor of the camera.
|
||||||
|
*/
|
||||||
|
void setZoom(float factor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position of the camera before any zoom transformations.
|
||||||
|
* Should only be used If you're zooming in and out while 2D projection mode is set in the director.
|
||||||
|
*/
|
||||||
|
const Vec2& getPositionCenter() { return _positionCenter; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of the camera with respect to the zoom factor.
|
||||||
|
* Should only be used If you're zooming in and out while 2D projection mode is set in the director.
|
||||||
|
*/
|
||||||
|
void setPositionCenter(const Vec2& position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of the camera with respect to the zoom factor.
|
||||||
|
* Should only be used If you're zooming in and out while 2D projection mode is set in the director.
|
||||||
|
*/
|
||||||
|
void setPositionCenter(float x, float y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Apply the zoom factor.
|
||||||
|
*/
|
||||||
|
void applyZoom();
|
||||||
|
|
||||||
|
void applyCustomProperties();
|
||||||
|
|
||||||
// override
|
// override
|
||||||
virtual void onEnter() override;
|
virtual void onEnter() override;
|
||||||
virtual void onExit() override;
|
virtual void onExit() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Before rendering scene with this camera, the background need to be cleared. It clears the depth buffer with max
|
Before rendering the scene with this camera, the background needs to be cleared.
|
||||||
depth by default. Use setBackgroundBrush to modify the default behavior
|
It will clear the depth buffer with max depth by default.
|
||||||
|
Use setBackgroundBrush to modify this default behavior.
|
||||||
*/
|
*/
|
||||||
void clearBackground();
|
void clearBackground();
|
||||||
/**
|
/**
|
||||||
|
@ -258,8 +330,8 @@ public:
|
||||||
void apply();
|
void apply();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the viewprojection matrix was updated since the last frame.
|
* Whether or not the viewprojection matrix was updated last frame.
|
||||||
* @return True if the viewprojection matrix was updated since the last frame.
|
* @return True if the viewprojection matrix was updated last frame.
|
||||||
*/
|
*/
|
||||||
bool isViewProjectionUpdated() const { return _viewProjectionUpdated; }
|
bool isViewProjectionUpdated() const { return _viewProjectionUpdated; }
|
||||||
|
|
||||||
|
@ -282,7 +354,7 @@ public:
|
||||||
~Camera();
|
~Camera();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the scene,this method shall not be invoke manually
|
* Set the owner scene of the camera, this method shall not be invoked manually
|
||||||
*/
|
*/
|
||||||
void setScene(Scene* scene);
|
void setScene(Scene* scene);
|
||||||
|
|
||||||
|
@ -300,7 +372,7 @@ protected:
|
||||||
static Camera* _visitingCamera;
|
static Camera* _visitingCamera;
|
||||||
static Viewport _defaultViewport;
|
static Viewport _defaultViewport;
|
||||||
|
|
||||||
Scene* _scene = nullptr; // Scene camera belongs to
|
Scene* _scene = nullptr; // Scene that owns this camera.
|
||||||
Mat4 _projection;
|
Mat4 _projection;
|
||||||
mutable Mat4 _view;
|
mutable Mat4 _view;
|
||||||
mutable Mat4 _viewInv;
|
mutable Mat4 _viewInv;
|
||||||
|
@ -320,6 +392,12 @@ protected:
|
||||||
mutable bool _frustumDirty = true;
|
mutable bool _frustumDirty = true;
|
||||||
int8_t _depth = -1; // camera depth, the depth of camera with CameraFlag::DEFAULT flag is 0 by default, a camera
|
int8_t _depth = -1; // camera depth, the depth of camera with CameraFlag::DEFAULT flag is 0 by default, a camera
|
||||||
// with larger depth is drawn on top of camera with smaller depth
|
// with larger depth is drawn on top of camera with smaller depth
|
||||||
|
Director::Projection _projectionType;
|
||||||
|
|
||||||
|
float _eyeZdistance; // Z eye projection distance for 2D in 3D projection.
|
||||||
|
float _zoomFactor; // The zoom factor of the camera. 3D = (cameraZDistance * _zoomFactor), 2D = (cameraScale * _zoomFactor)
|
||||||
|
float _zoomFactorFarPlane;
|
||||||
|
Vec2 _positionCenter;
|
||||||
|
|
||||||
CameraBackgroundBrush* _clearBrush = nullptr; // brush used to clear the back ground
|
CameraBackgroundBrush* _clearBrush = nullptr; // brush used to clear the back ground
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue