#include //Perspective Camera Class, Used to compute camera transforms class ZPerspectiveCamera { protected: bool transformDirty; //Dirty flag for computing camera transform SST_Mat44f CameraTransform; SST_Vec3f EyePoint; SST_Vec3f ForwardVec; SST_Vec3f UpVec; SST_Vec3f RightVec; float NearClip; float FarClip; float XFov; float AspectRatio; void ComputeCameraTransform() { SST_Mat44f perspectiveMatrix; SST_Mat44f viewMatrix; SST_Vec3f target = {ForwardVec.x + EyePoint.x, ForwardVec.y + EyePoint.y, ForwardVec.z + EyePoint.z}; SST_Math_Mat44fCreatePerspective(&perspectiveMatrix, this->XFov, this->AspectRatio, this->NearClip, this->FarClip); SST_Math_Mat44fCreateLookAt(&viewMatrix, &this->EyePoint, &target, &this->UpVec); SST_Math_Mat44fMultiplyMatrix(&perspectiveMatrix, &viewMatrix, &this->CameraTransform); this->transformDirty = false; } //Flags the transform as 'dirty' void FlagTransforms() { this->transformDirty = true; } public: ZPerspectiveCamera() { SST_Vec3f eye = { 0, 0, 0 }; SST_Vec3f forward = { 0, 1, 0 }; SST_Vec3f up = { 0, 0, 1 }; SST_Vec3f right = { 1, 0, 1 }; SetEyePoint(&eye); SetForwardVec(&forward); SetUpVec(&up); SetRightVec(&right); NearClip = 1.0f; FarClip = 10000.0f; XFov = 90.0f; AspectRatio = 1.0f; this->transformDirty = true; } //Getters for camera data const SST_Vec3f* GetEyePoint() { return &EyePoint; } const SST_Vec3f* GetForwardVec() { return &ForwardVec; } const SST_Vec3f* GetUpVec() { return &UpVec; } const SST_Vec3f* GetRightVec() { return &RightVec; } float GetNearClip() { return NearClip; } float GetFarClip() { return FarClip; } float GetXFov() { return XFov; } float GetAspectRatio() { return AspectRatio; } //Setters for camera data. Will flag the transform as 'dirty' void SetEyePoint(const SST_Vec3f* _eye) { EyePoint = *_eye; FlagTransforms(); } void SetForwardVec(const SST_Vec3f* _forward) { ForwardVec = *_forward; FlagTransforms(); } void SetUpVec(const SST_Vec3f* _up) { UpVec = *_up; FlagTransforms(); } void SetRightVec(const SST_Vec3f* _right) { RightVec = *_right; FlagTransforms(); } void SetNearClip(float _nearClip) { NearClip = _nearClip; FlagTransforms(); } void SetFarClip(float _farClip) { FarClip = _farClip; FlagTransforms(); } void SetXFov(float _xFov) { XFov = _xFov; FlagTransforms(); } void SetAspectRatio(float _ratio) { AspectRatio = _ratio; FlagTransforms(); } //Movement methods, which move the camera in the direction if it's basis vectors by a factor void MoveForward(float t) { SST_Vec3f tmp; SST_Math_Vec3fScale(&ForwardVec, t, &tmp); SST_Math_Vec3fAddLocal(&EyePoint, &tmp); FlagTransforms(); } void MoveUp(float t) { SST_Vec3f tmp; SST_Math_Vec3fScale(&UpVec, t, &tmp); SST_Math_Vec3fAddLocal(&EyePoint, &tmp); FlagTransforms(); } void MoveRight(float t) { SST_Vec3f tmp; SST_Math_Vec3fScale(&RightVec, t, &tmp); SST_Math_Vec3fAddLocal(&EyePoint, &tmp); FlagTransforms(); } //Rotation Methods, which rotate the camera about it's basis vectors void RotateUp(float t) { SST_Math_Vec3fRotateAboutLocal(&this->ForwardVec, &this->RightVec, t); SST_Math_Vec3fRotateAboutLocal(&this->UpVec, &this->RightVec, t); FlagTransforms(); } void RotateRight(float t) { SST_Math_Vec3fRotateAboutLocal(&this->ForwardVec, &this->UpVec, t); SST_Math_Vec3fRotateAboutLocal(&this->RightVec, &this->UpVec, t); FlagTransforms(); } void RotateClockwise(float t) { SST_Math_Vec3fRotateAboutLocal(&this->UpVec, &this->ForwardVec, t); SST_Math_Vec3fRotateAboutLocal(&this->RightVec, &this->ForwardVec, t); FlagTransforms(); } //Camera transform getters, which will trigger a recompute of the transform matrix if need be const SST_Mat44f* GetCameraTransform() { if (this->transformDirty) { this->ComputeCameraTransform(); } return &this->CameraTransform; } };