Files
UnrealEngine/Engine/Source/ThirdParty/MaterialX/MaterialX-1.38.10/source/MaterialXRender/Camera.h
2025-05-18 13:04:45 +08:00

207 lines
5.8 KiB
C++

//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//
#ifndef MATERIALX_CAMERA_H
#define MATERIALX_CAMERA_H
#include <MaterialXRender/Types.h>
MATERIALX_NAMESPACE_BEGIN
/// Shared pointer to a Camera
using CameraPtr = std::shared_ptr<class Camera>;
/// @class Camera
/// A simple camera class, supporting transform matrices and arcball
/// functionality for object-viewing applications.
class MX_RENDER_API Camera
{
public:
Camera() :
_worldMatrix(Matrix44::IDENTITY),
_viewMatrix(Matrix44::IDENTITY),
_projectionMatrix(Matrix44::IDENTITY),
_arcballActive(false),
_arcballQuat(Quaternion::IDENTITY),
_arcballDelta(Quaternion::IDENTITY),
_arcballSpeed(2.0f)
{
}
~Camera() { }
/// Create a new camera.
static CameraPtr create() { return std::make_shared<Camera>(); }
/// @name Transform Matrices
/// @{
/// Set the world matrix.
void setWorldMatrix(const Matrix44& mat)
{
_worldMatrix = mat;
}
/// Return the world matrix.
const Matrix44& getWorldMatrix() const
{
return _worldMatrix;
}
/// Set the view matrix.
void setViewMatrix(const Matrix44& mat)
{
_viewMatrix = mat;
}
/// Return the view matrix.
const Matrix44& getViewMatrix() const
{
return _viewMatrix;
}
/// Set the projection matrix.
void setProjectionMatrix(const Matrix44& mat)
{
_projectionMatrix = mat;
}
/// Return the projection matrix.
const Matrix44& getProjectionMatrix() const
{
return _projectionMatrix;
}
/// Compute our full model-view-projection matrix.
Matrix44 getWorldViewProjMatrix() const
{
return _worldMatrix * _viewMatrix * _projectionMatrix;
}
/// Derive viewer position from the view matrix.
Vector3 getViewPosition() const
{
Matrix44 invView = _viewMatrix.getInverse();
return Vector3(invView[3][0], invView[3][1], invView[3][2]);
}
/// Derive viewer direction from the view matrix.
Vector3 getViewDirection() const
{
Matrix44 invView = _viewMatrix.getInverse();
return Vector3(invView[2][0], invView[2][1], invView[2][2]);
}
/// @}
/// @name Viewport
/// @{
/// Set the size of the viewport window.
void setViewportSize(const Vector2& size)
{
_viewportSize = size;
}
/// Return the size of the viewport window.
const Vector2& getViewportSize() const
{
return _viewportSize;
}
/// Project a position from object to viewport space.
Vector3 projectToViewport(Vector3 v)
{
v = transformPointPerspective(getWorldViewProjMatrix(), v);
v = v * 0.5f + Vector3(0.5f);
v[0] *= _viewportSize[0];
v[1] *= _viewportSize[1];
return v;
}
/// Unproject a position from viewport to object space.
Vector3 unprojectFromViewport(Vector3 v)
{
v[0] /= _viewportSize[0];
v[1] /= _viewportSize[1];
v = v * 2.0f - Vector3(1.0f);
v = transformPointPerspective(getWorldViewProjMatrix().getInverse(), v);
return v;
}
/// @}
/// @name Arcball
/// @{
/// Indicates a button state change, with pos being the instantaneous location of the mouse.
void arcballButtonEvent(const Vector2& pos, bool pressed);
/// Apply mouse motion to the arcball state.
bool applyArcballMotion(const Vector2& pos);
/// Return the arcball matrix.
Matrix44 arcballMatrix() const
{
return (_arcballDelta * _arcballQuat).toMatrix();
}
/// @}
/// @name Utilities
/// @{
/// Create a view matrix given an eye position, a target position and an up vector.
static Matrix44 createViewMatrix(const Vector3& eye,
const Vector3& target,
const Vector3& up);
/// Create a perpective projection matrix given a set of clip planes with [-1,1] projected Z.
static Matrix44 createPerspectiveMatrix(float left, float right,
float bottom, float top,
float nearP, float farP);
/// Create an orthographic projection matrix given a set of clip planes with [-1,1] projected Z.
static Matrix44 createOrthographicMatrix(float left, float right,
float bottom, float top,
float nearP, float farP);
/// Create a perpective projection matrix given a set of clip planes with [0,1] projected Z.
static Matrix44 createPerspectiveMatrixZP(float left, float right,
float bottom, float top,
float nearP, float farP);
/// Create an orthographic projection matrix given a set of clip planes with [0,1] projected Z.
static Matrix44 createOrthographicMatrixZP(float left, float right,
float bottom, float top,
float nearP, float farP);
/// Apply a perspective transform to the given 3D point, performing a
/// homogeneous divide on the transformed result.
static Vector3 transformPointPerspective(const Matrix44& m, const Vector3& v)
{
Vector4 res = m.multiply(Vector4(v[0], v[1], v[2], 1.0f));
return Vector3(res[0], res[1], res[2]) / res[3];
}
/// @}
protected:
// Transform matrices
Matrix44 _worldMatrix;
Matrix44 _viewMatrix;
Matrix44 _projectionMatrix;
// Viewport size
Vector2 _viewportSize;
// Arcball properties
bool _arcballActive;
Vector2 _arcballLastPos;
Quaternion _arcballQuat;
Quaternion _arcballDelta;
float _arcballSpeed;
};
MATERIALX_NAMESPACE_END
#endif