|
- #include "sww/camera.h"
-
- #if 0
- #include "sww/vmath.h"
-
- struct swwCameraVirtualTable {};
-
- struct swwCamera {
- Matrix4x4f view;
- Matrix4x4f projection;
- Matrix4x4f view_projection;
-
- Matrix4x4f world;
- Vector3f position;
- Quaternionf orientation;
-
- float aspect;
- float fov;
- float near_z;
- float far_z;
-
- void (*create_projection)();
- };
-
- swwCamera* swwCamera_Create(float aspect, float far)
- {
-
- }
-
- void swwCamera_Destroy(swwCamera* o)
- {
-
- }
-
- static inline float ScalarModAngle(float angle) {
- // Note: The modulo is performed with unsigned math only to work
- // around a precision error on numbers that are close to PI
-
- // Normalize the range from 0.0f to XM_2PI
- angle = angle + M_PI;
- // Perform the modulo, unsigned
- float ftemp = fabsf(angle);
- ftemp = ftemp - (M_PI * 2 * (float)((int32_t)(ftemp / M_2PI)));
- // Restore the number to the range of -XM_PI to XM_PI-epsilon
- ftemp = ftemp - M_PI;
- // If the modulo'd value was negative, restore negation
- if (angle < 0.0f) {
- ftemp = -ftemp;
- }
-
- return ftemp;
- }
-
- Float3 Camera::Forward() const { return world.Forward(); }
-
- Float3 Camera::Back() const { return world.Back(); }
-
- Float3 Camera::Up() const { return world.Up(); }
-
- Float3 Camera::Down() const { return world.Down(); }
-
- Float3 Camera::Right() const { return world.Right(); }
-
- Float3 Camera::Left() const { return world.Left(); }
-
- void Camera::SetLookAt(const Float3 &eye, const Float3 &lookAt,
- const Float3 &up) {
- view = XMMatrixLookAtLH(eye.ToSIMD(), lookAt.ToSIMD(), up.ToSIMD());
- world = Float4x4::Invert(view);
- position = eye;
- orientation = XMQuaternionRotationMatrix(world.ToSIMD());
-
- WorldMatrixChanged();
- }
-
- void Camera::SetWorldMatrix(const Float4x4 &newWorld) {
- world = newWorld;
- position = world.Translation();
- orientation = XMQuaternionRotationMatrix(world.ToSIMD());
-
- WorldMatrixChanged();
- }
-
- void Camera::SetPosition(const Float3 &newPosition) {
- position = newPosition;
- world.SetTranslation(newPosition);
-
- WorldMatrixChanged();
- }
-
- void Camera::SetOrientation(const Quaternion &newOrientation) {
- world = XMMatrixRotationQuaternion(newOrientation.ToSIMD());
- orientation = newOrientation;
- world.SetTranslation(position);
-
- WorldMatrixChanged();
- }
-
- void Camera::SetNearClip(float newNearClip) {
- nearZ = newNearClip;
- CreateProjection();
- }
-
- void Camera::SetFarClip(float newFarClip) {
- farZ = newFarClip;
- CreateProjection();
- }
-
- void Camera::SetProjection(const Float4x4 &newProjection) {
- projection = newProjection;
- viewProjection = view * projection;
- }
-
- //=================================================================================================
- // OrthographicCamera
- //=================================================================================================
-
- OrthographicCamera::OrthographicCamera(float minX, float minY, float maxX,
- float maxY, float nearClip,
- float farClip)
- : Camera(nearClip, farClip), xMin(minX), yMin(minY), xMax(maxX), yMax(maxY)
-
- {
- Assert_(xMax > xMin && yMax > yMin);
-
- CreateProjection();
- }
-
- OrthographicCamera::~OrthographicCamera() {}
-
- void OrthographicCamera::CreateProjection() {
- projection =
- XMMatrixOrthographicOffCenterLH(xMin, xMax, yMin, yMax, nearZ, farZ);
- viewProjection = view * projection;
- }
-
- void OrthographicCamera::SetMinX(float minX) {
- xMin = minX;
- CreateProjection();
- }
-
- void OrthographicCamera::SetMinY(float minY) {
- yMin = minY;
- CreateProjection();
- }
-
- void OrthographicCamera::SetMaxX(float maxX) {
- xMax = maxX;
- CreateProjection();
- }
-
- void OrthographicCamera::SetMaxY(float maxY) {
- yMax = maxY;
- CreateProjection();
- }
-
- //=================================================================================================
- // PerspectiveCamera
- //=================================================================================================
-
- PerspectiveCamera::PerspectiveCamera(float aspectRatio, float fieldOfView,
- float nearClip, float farClip)
- : Camera(nearClip, farClip), aspect(aspectRatio), fov(fieldOfView) {
- Assert_(aspectRatio > 0);
- Assert_(fieldOfView > 0 && fieldOfView <= 3.14159f);
- CreateProjection();
- }
-
- PerspectiveCamera::~PerspectiveCamera() {}
-
- void PerspectiveCamera::SetAspectRatio(float aspectRatio) {
- aspect = aspectRatio;
- CreateProjection();
- }
-
- void PerspectiveCamera::SetFieldOfView(float fieldOfView) {
- fov = fieldOfView;
- CreateProjection();
- }
-
- void PerspectiveCamera::CreateProjection() {
- projection = XMMatrixPerspectiveFovLH(fov, aspect, nearZ, farZ);
- viewProjection = view * projection;
- }
-
- //=================================================================================================
- // FirstPersonCamera
- //=================================================================================================
-
- FirstPersonCamera::FirstPersonCamera(float aspectRatio, float fieldOfView,
- float nearClip, float farClip)
- : PerspectiveCamera(aspectRatio, fieldOfView, nearClip, farClip), xRot(0),
- yRot(0) {}
-
- void swwCamera_WorldMatrixChanged(swwCamera *o) {
- o->view = Matrix4x4f_Invert(o->world);
- o->view_projection = o->view * o->projection;
- }
-
- void swwCamera_Construct(swwCamera *o, float near_z, float far_z) {
- Matrix4x4f_SetIdentity(o->world);
- Matrix4x4f_SetIdentity(o->view);
- o->position = {0.0f, 0.0f, 0.0f};
- Quaternionf_SetIdentity(o->orientation);
- }
-
- void swwCamera_Destruct(swwCamera *o) {}
-
- const Matrix4x4f *swwCamera_ViewMatrix(swwCamera *o) { return o->view; }
- const Matrix4x4f *swwCamera_ProjectionMatrix(swwCamera *o) {
- return o->projection;
- }
- const Matrix4x4f *swwCamera_ViewProjectionMatrix(swwCamera *o) {
- return o->view_projection;
- }
- const Matrix4x4f *swwCamera_WorldMatrix(swwCamera *o) { return o->world; }
- const Vector3f *swwCamera_Position(swwCamera *o) { return o->position; }
- const Quaternionf *swwCamera_Orientation(swwCamera *o) {
- return o->orientation;
- }
- float swwCamera_NearClip(swwCamera *o) { return o->near_z; }
- float swwCamera_FarClip(swwCamera *o) { return o->far_z; }
-
- Vector3f swwCamera_Forward(swwCamera *o);
- Vector3f swwCamera_Back(swwCamera *o);
- Vector3f swwCamera_Up(swwCamera *o);
- Vector3f swwCamera_Down(swwCamera *o);
- Vector3f swwCamera_Right(swwCamera *o);
- Vector3f swwCamera_Left(swwCamera *o);
-
- void swwCamera_SetLookAt(swwCamera *o, const Vector3f *eye,
- const Vector3f *look_at, const Vector3f *up);
- void swwCamera_SetWorldMatrix(swwCamera *o, const Matrix4x4f *new_world);
- void swwCamera_SetPosition(swwCamera *o, const Vector3f *new_position);
- void swwCamera_SetOrientation(swwCamera *o, const Quaternionf *new_orientation);
- void swwCamera_SetNearClip(swwCamera *o, float new_near_clip);
- void swwCamera_SetFarClip(swwCamera *o, float new_far_clip);
- void swwCamera_SetProjection(swwCamera *o, const Matrix4x4f *new_projection);
-
- // Camera with an orthographic projection
- struct swwOrthographicCamera {
- float x_min;
- float x_max;
- float y_min;
- float y_max;
-
- void CreateProjection();
- };
-
- swwOrthographicCamera *swwOrthographicCamera_Create(float minX, float minY,
- float maxX, float maxY,
- float nearClip,
- float farClip);
-
- float swwOrthographicCamera_MinX(swwOrthographicCamera *o) { return o->x_min; }
- float swwOrthographicCamera_MinY(swwOrthographicCamera *o) { return o->y_min; }
- float swwOrthographicCamera_MaxX(swwOrthographicCamera *o) { return o->x_max; }
- float swwOrthographicCamera_MaxY(swwOrthographicCamera *o) { return o->y_max; }
-
- void swwOrthographicCamera_SetMinX(swwOrthographicCamera *o, float minX);
- void swwOrthographicCamera_SetMinY(swwOrthographicCamera *o, float minY);
- void swwOrthographicCamera_SetMaxX(swwOrthographicCamera *o, float maxX);
- void swwOrthographicCamera_SetMaxY(swwOrthographicCamera *o, float maxY);
-
- // Camera with a perspective projection
- class swwPerspectiveCamera {
- float aspect;
- float fov;
-
- void CreateProjection();
- };
-
- swwPerspectiveCamera *swwPerspectiveCamera_Create(float aspectRatio,
- float fieldOfView,
- float nearClip,
- float farClip);
-
- float swwPerspectiveCamera_AspectRatio(swwPerspectiveCamera *o) {
- return o->aspect;
- };
- float swwPerspectiveCamera_FieldOfView(swwPerspectiveCamera *o) {
- return o->fov;
- };
-
- void swwPerspectiveCamera_SetAspectRatio(swwPerspectiveCamera *o,
- float aspectRatio);
- void swwPerspectiveCamera_SetFieldOfView(swwPerspectiveCamera *o,
- float fieldOfView);
-
- // Perspective camera that rotates about Z and Y axes
- struct swwFirstPersonCamera {
- float x_rot;
- float y_rot;
- };
-
- swwFirstPersonCamera *
- swwFirstPersonCamera_Create(float aspectRatio = 16.0f / 9.0f,
- float fieldOfView = Pi_4, float nearClip = 0.01f,
- float farClip = 100.0f);
-
- float swwFirstPersonCamera_XRotation(swwFirstPersonCamera *o) {
- return o->x_rot;
- };
- float swwFirstPersonCamera_YRotation(swwFirstPersonCamera *o) {
- return o->y_rot;
- };
-
- void swwFirstPersonCamera_SetXRotation(swwFirstPersonCamera *o,
- float x_rotation) {
-
- o->x_rot = Clampf(x_rotation, -M_PI / 2.f, M_PI / 2.f);
- swwCamera_SetOrientation(
- (swwCamera *)o, Quaternionf_RotationRollPitchYaw(o->x_rot, o->y_rot, 0));
- }
-
- void swwFirstPersonCamera_SetYRotation(swwFirstPersonCamera *o,
- float y_rotation) {
-
- o->y_rot = ScalarModAngle(y_rotation);
- swwCamera_SetOrientation(
- (swwCamera *)o, Quaternionf_RotationRollPitchYaw(o->x_rot, o->y_rot, 0));
- }
- #endif /* COMMENT */
|