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
|
||||
|
||||
Camera::Camera()
|
||||
: _eyeZdistance(1)
|
||||
, _zoomFactor(1)
|
||||
, _nearPlane(-1024)
|
||||
, _farPlane(1024)
|
||||
, _zoomFactorFarPlane(1024)
|
||||
, _positionCenter({0, 0})
|
||||
{
|
||||
// minggo comment
|
||||
// _frustum.setClipZ(true);
|
||||
|
@ -137,6 +143,7 @@ void Camera::lookAt(const Vec3& lookAtPos, const Vec3& up)
|
|||
Vec3::cross(zaxis, xaxis, &yaxis);
|
||||
yaxis.normalize();
|
||||
Mat4 rotation;
|
||||
|
||||
rotation.m[0] = xaxis.x;
|
||||
rotation.m[1] = xaxis.y;
|
||||
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[6] = yaxis.z;
|
||||
rotation.m[7] = 0;
|
||||
|
||||
rotation.m[8] = zaxis.x;
|
||||
rotation.m[9] = zaxis.y;
|
||||
rotation.m[10] = zaxis.z;
|
||||
|
@ -177,6 +185,8 @@ void Camera::setAdditionalProjection(const Mat4& mat)
|
|||
|
||||
bool Camera::initDefault()
|
||||
{
|
||||
_projectionType = Director::getInstance()->getProjection();
|
||||
|
||||
auto size = _director->getWinSize();
|
||||
// create default camera
|
||||
auto projection = _director->getProjection();
|
||||
|
@ -185,7 +195,7 @@ bool Camera::initDefault()
|
|||
case Director::Projection::_2D:
|
||||
{
|
||||
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));
|
||||
break;
|
||||
}
|
||||
|
@ -195,6 +205,7 @@ bool Camera::initDefault()
|
|||
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),
|
||||
up(0.0f, 1.0f, 0.0f);
|
||||
_eyeZdistance = eye.z;
|
||||
setPosition3D(eye);
|
||||
lookAt(center, up);
|
||||
break;
|
||||
|
@ -203,15 +214,19 @@ bool Camera::initDefault()
|
|||
CCLOG("unrecognized projection");
|
||||
break;
|
||||
}
|
||||
if (_zoomFactor != 1.0F)
|
||||
applyZoom();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Camera::initPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
|
||||
{
|
||||
_fieldOfView = fieldOfView;
|
||||
_aspectRatio = aspectRatio;
|
||||
_nearPlane = nearPlane;
|
||||
_farPlane = farPlane;
|
||||
_fieldOfView = fieldOfView;
|
||||
_aspectRatio = aspectRatio;
|
||||
_nearPlane = nearPlane;
|
||||
_farPlane = farPlane;
|
||||
if (_zoomFactorFarPlane == 1024)
|
||||
_zoomFactorFarPlane = farPlane;
|
||||
Mat4::createPerspective(_fieldOfView, _aspectRatio, _nearPlane, _farPlane, &_projection);
|
||||
_viewProjectionDirty = 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()
|
||||
{
|
||||
if (_scene == nullptr)
|
||||
|
@ -431,6 +522,30 @@ int Camera::getRenderOrder() const
|
|||
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)
|
||||
{
|
||||
_viewProjectionUpdated = _transformUpdated;
|
||||
|
|
|
@ -234,22 +234,94 @@ public:
|
|||
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; }
|
||||
|
||||
/**
|
||||
* 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; }
|
||||
|
||||
/**
|
||||
* 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
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
||||
/**
|
||||
Before rendering scene with this camera, the background need to be cleared. It clears the depth buffer with max
|
||||
depth by default. Use setBackgroundBrush to modify the default behavior
|
||||
Before rendering the scene with this camera, the background needs to be cleared.
|
||||
It will clear the depth buffer with max depth by default.
|
||||
Use setBackgroundBrush to modify this default behavior.
|
||||
*/
|
||||
void clearBackground();
|
||||
/**
|
||||
|
@ -258,8 +330,8 @@ public:
|
|||
void apply();
|
||||
|
||||
/**
|
||||
* Whether or not the viewprojection matrix was updated since the last frame.
|
||||
* @return True if 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 last frame.
|
||||
*/
|
||||
bool isViewProjectionUpdated() const { return _viewProjectionUpdated; }
|
||||
|
||||
|
@ -282,7 +354,7 @@ public:
|
|||
~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);
|
||||
|
||||
|
@ -300,7 +372,7 @@ protected:
|
|||
static Camera* _visitingCamera;
|
||||
static Viewport _defaultViewport;
|
||||
|
||||
Scene* _scene = nullptr; // Scene camera belongs to
|
||||
Scene* _scene = nullptr; // Scene that owns this camera.
|
||||
Mat4 _projection;
|
||||
mutable Mat4 _view;
|
||||
mutable Mat4 _viewInv;
|
||||
|
@ -320,6 +392,12 @@ protected:
|
|||
mutable bool _frustumDirty = true;
|
||||
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
|
||||
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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue