diff --git a/src/camera.cc b/src/camera.cc index 4605497..86ed8be 100644 --- a/src/camera.cc +++ b/src/camera.cc @@ -3,29 +3,45 @@ * Eryn Wells */ -#include "camera.h" +#include "camera.hh" #include "log.hh" #define LOG_NAME "camera" #include "logModule.hh" +using charles::basics::Ray; +using charles::basics::Vector4; + + +namespace charles { + #pragma mark - Generic Camera +/* + * charles::Camera::Camera -- + */ Camera::Camera() - : mDirection(Vector3::Z), + : mDirection(0, 0, 1), mRight(1.33, 0, 0), - mUp(Vector3::Y) + mUp(0, 1, 0) { } -Camera::Camera(const Camera& other) - : mDirection(other.mDirection), - mRight(other.mRight), - mUp(other.mUp) +/* + * charles::Camera::Camera -- + */ +Camera::Camera(const Camera& rhs) + : mOrigin(rhs.mOrigin), + mDirection(rhs.mDirection), + mRight(rhs.mRight), + mUp(rhs.mUp) { } +/* + * charles::Camera::~Camera -- + */ Camera::~Camera() { } @@ -33,7 +49,17 @@ Camera::~Camera() /* * Camera::GetOrigin -- */ -const Vector3& +Vector4& +Camera::GetOrigin() +{ + return mOrigin; +} + + +/* + * Camera::GetOrigin -- + */ +const Vector4& Camera::GetOrigin() const { @@ -45,27 +71,57 @@ Camera::GetOrigin() * Camera::SetOrigin -- */ void -Camera::SetOrigin(const Vector3 &origin) +Camera::SetOrigin(const Vector4& origin) { mOrigin = origin; } -const Vector3& -Camera::get_direction() +/* + * Camera::GetDirection -- + */ +Vector4& +Camera::GetDirection() +{ + return mDirection; +} + + +/* + * Camera::GetDirection -- + */ +const Vector4& +Camera::GetDirection() const { return mDirection; } + +/* + * Camera::SetDirection -- + */ void -Camera::set_direction(const Vector3 &direction) +Camera::SetDirection(const Vector4& direction) { mDirection = direction; } -const Vector3& +/* + * Camera::GetRight -- + */ +Vector4& +Camera::GetRight() +{ + return mRight; +} + + +/* + * Camera::GetRight -- + */ +const Vector4& Camera::GetRight() const { @@ -73,14 +129,30 @@ Camera::GetRight() } +/* + * Camera::SetRight -- + */ void -Camera::SetRight(const Vector3& right) +Camera::SetRight(const Vector4& right) { mRight = right; } -const Vector3& +/* + * Camera::GetUp -- + */ +Vector4& +Camera::GetUp() +{ + return mUp; +} + + +/* + * Camera::GetUp -- + */ +const Vector4& Camera::GetUp() const { @@ -88,13 +160,19 @@ Camera::GetUp() } +/* + * Camera::SetUp -- + */ void -Camera::SetUp(const Vector3& up) +Camera::SetUp(const Vector4& up) { mUp = up; } +/* + * Camera::IsLeftHanded -- + */ bool Camera::IsLeftHanded() const @@ -110,24 +188,27 @@ Camera::IsLeftHanded() * than 0, the vector is pointing left of the up-direction plane and the * coordinate system is left-handed. */ - return mUp.cross(mDirection).dot(mRight) < 0.0; + return mUp.Cross(mDirection).Dot(mRight) < 0.0; } +/* + * Camera::LookAt -- + */ void -Camera::LookAt(const Vector3& pt) +Camera::LookAt(const Vector4& p) { /* * Precalulate these in order to preserve the aspect ratio and orientation * of the camera across the LookAt operation. */ - const Double directionLength = mDirection.length(); - const Double rightLength = mRight.length(); - const Double upLength = mUp.length(); + const Double directionLength = mDirection.Length(); + const Double rightLength = mRight.Length(); + const Double upLength = mUp.Length(); const bool isLeftHanded = IsLeftHanded(); /* Orient the camera towards the point. */ - mDirection = (pt - mOrigin).normalize(); + mDirection = basics::Normalized(p - mOrigin); /* TODO: Check for zero length direction vector. */ /* @@ -141,8 +222,8 @@ Camera::LookAt(const Vector3& pt) * specifies the vector along which LookAt pans and tilts the camera. It * might be worth looking into, at some point. */ - mRight = Vector3::Y.cross(mDirection).normalize(); - mUp = mDirection.cross(mRight); + mRight = basics::Normalized(Vector4(0, 1, 0).Cross(mDirection)); + mUp = mDirection.Cross(mRight); /* * Now, fix up the direction, right, and up vectors so that their magnitudes @@ -152,10 +233,13 @@ Camera::LookAt(const Vector3& pt) mRight *= isLeftHanded ? rightLength : -rightLength; mUp *= upLength; - LOG_DEBUG << "Camera is looking at " << pt; + LOG_DEBUG << "Camera is looking at " << p; } +/* + * charles::Camera::GetTypeString -- + */ std::string Camera::GetTypeString() const @@ -164,6 +248,9 @@ Camera::GetTypeString() } +/* + * charles::Camera::WriteType -- + */ void Camera::WriteType(std::ostream& ost) const @@ -184,23 +271,23 @@ PerspectiveCamera::PerspectiveCamera(const Camera& other) Ray -PerspectiveCamera::compute_primary_ray(const int x, - const int width, - const int y, - const int height) +PerspectiveCamera::PrimaryRay(const int x, + const int width, + const int y, + const int height) const { /* * Center x and y in the pixel and convert them to be coordinates between * -0.5 and 0.5. */ - double x0 = (x + 0.5) / width - 0.5; - double y0 = ((height - 1.0) - (y - 0.5)) / height - 0.5; + Double x0 = (x + 0.5) / width - 0.5; + Double y0 = ((height - 1.0) - (y - 0.5)) / height - 0.5; - Vector3 direction = LinearCombination(1.0, get_direction(), + Vector4 direction = LinearCombination(1.0, GetDirection(), x0, GetRight(), y0, GetUp()); - return Ray(GetOrigin(), direction.normalize()); + return Ray(GetOrigin(), basics::Normalized(direction)); } @@ -226,30 +313,24 @@ OrthographicCamera::OrthographicCamera(const Camera& other) /* * OrthographicCamera::compute_primary_ray -- */ -/** - * Compute a primary ray given an (x,y) coordinate pair. The orthographic camera - * projects rays parallel to the viewing direction through the (x,y) coordinate - * given. Thus, the size of the orthographic camera should be set to the size of - * the view into the scene. - */ Ray -OrthographicCamera::compute_primary_ray(const int x, - const int width, - const int y, - const int height) +OrthographicCamera::PrimaryRay(const int x, + const int width, + const int y, + const int height) const { /* * Center x and y in the pixel and convert them to be coordinates between * -0.5 and 0.5. */ - double x0 = (x + 0.5) / width + 0.5; - double y0 = ((height - 1.0) - (y - 0.5)) / height - 0.5; + Double x0 = (x + 0.5) / width + 0.5; + Double y0 = ((height - 1.0) - (y - 0.5)) / height - 0.5; - Vector3 origin = LinearCombination(1.0, GetOrigin(), + Vector4 origin = LinearCombination(1.0, GetOrigin(), x0, GetRight(), y0, GetUp()); - return Ray(origin, get_direction()); + return Ray(origin, GetDirection()); } @@ -274,3 +355,5 @@ operator<<(std::ostream& ost, << "]"; return ost; } + +} /* namespace charles */ diff --git a/src/camera.h b/src/camera.h deleted file mode 100644 index f3b46d1..0000000 --- a/src/camera.h +++ /dev/null @@ -1,117 +0,0 @@ -/* camera.h - * - * The Camera is the eye into the scene. It defines several parameters and a - * single compute_primary_ray method that generates rays with which the ray - * tracer draws the scene. - * - * Eryn Wells - */ - -#ifndef __CAMERA_H__ -#define __CAMERA_H__ - -#include - -#include "basics.h" - - -struct Camera -{ - typedef std::shared_ptr Ptr; - - Camera(); - Camera(const Camera& other); - virtual ~Camera(); - - const Vector3& GetOrigin() const; - void SetOrigin(const Vector3& origin); - - const Vector3& get_direction() const; - void set_direction(const Vector3& direction); - - const Vector3& GetRight() const; - void SetRight(const Vector3& right); - - const Vector3& GetUp() const; - void SetUp(const Vector3& up); - - /** - * Get the camera's handedness. Left handed is the default. - * - * @returns `true` if the camera is set up for left-handed coordinates. - */ - bool IsLeftHanded() const; - - /** - * Pan and tilt the camera towards the given point. - * - * @param [in] pt The point at which to face the camera - */ - void LookAt(const Vector3& pt); - - virtual Ray compute_primary_ray(const int x, const int width, - const int y, const int height) const = 0; - - virtual std::string GetTypeString() const; - -private: - friend std::ostream& operator<<(std::ostream& ost, const Camera& camera); - - void WriteType(std::ostream& ost) const; - - /** - * The location of the camera in the scene. Depending on the type of camera, - * this is the point from which rays will be emitted. - */ - Vector3 mOrigin; - - /** A normalized vector defining where the camera is pointed. */ - Vector3 mDirection; - - /** - * A vector defining the width of the camera's image plane. The ratio of - * this and mUp determine the aspect ratio of the image. - */ - Vector3 mRight; - - /** - * A vector defining the height of the camera's image plane. The ratio of - * this and mRight determine the aspect ratio of the image. - */ - Vector3 mUp; -}; - - -class PerspectiveCamera - : public Camera -{ -public: - PerspectiveCamera(); - PerspectiveCamera(const Camera& other); - - Ray compute_primary_ray(const int x, const int width, - const int y, const int height) const; - -private: - std::string GetTypeString() const; -}; - - -class OrthographicCamera - : public Camera -{ -public: - OrthographicCamera(); - OrthographicCamera(const Camera& other); - - Ray compute_primary_ray(const int x, const int width, - const int y, const int height) const; - -private: - std::string GetTypeString() const; -}; - - -std::ostream& operator<<(std::ostream& ost, const Camera& camera); - -#endif diff --git a/src/camera.hh b/src/camera.hh new file mode 100644 index 0000000..2b006da --- /dev/null +++ b/src/camera.hh @@ -0,0 +1,125 @@ +/* camera.hh + * vim: set tw=80: + * Eryn Wells + */ + +#ifndef __CAMERA_H__ +#define __CAMERA_H__ + +#include + +#include "basics/basics.hh" + + +namespace charles { + +/** + * The Camera is the eye into the scene. It defines several parameters and a + * single compute_primary_ray method that generates rays with which the ray + * tracer draws the scene. + */ +struct Camera +{ + typedef std::shared_ptr Ptr; + + Camera(); + Camera(const Camera& other); + virtual ~Camera(); + + basics::Vector4& GetOrigin(); + const basics::Vector4& GetOrigin() const; + void SetOrigin(const basics::Vector4& origin); + + basics::Vector4& GetDirection(); + const basics::Vector4& GetDirection() const; + void SetDirection(const basics::Vector4& direction); + + basics::Vector4& GetRight(); + const basics::Vector4& GetRight() const; + void SetRight(const basics::Vector4& right); + + basics::Vector4& GetUp(); + const basics::Vector4& GetUp() const; + void SetUp(const basics::Vector4& up); + + /** Get the camera's handedness. Left handed is the default. */ + bool IsLeftHanded() const; + + /** Pan and tilt the camera towards the given point. */ + void LookAt(const basics::Vector4& p); + + virtual basics::Ray PrimaryRay(const int x, const int width, + const int y, const int height) const = 0; + +protected: + virtual std::string GetTypeString() const; + +private: + friend std::ostream& operator<<(std::ostream& ost, const Camera& camera); + + void WriteType(std::ostream& ost) const; + + /** + * The location of the camera in the scene. Depending on the type of camera, + * this is the point from which rays will be emitted. + */ + basics::Vector4 mOrigin; + + /** A vector defining where the camera is pointed. */ + basics::Vector4 mDirection; + + /** + * A vector defining the width of the camera's image plane. The ratio of + * this and mUp determine the aspect ratio of the image. + */ + basics::Vector4 mRight; + + /** + * A vector defining the height of the camera's image plane. The ratio of + * this and mRight determine the aspect ratio of the image. + */ + basics::Vector4 mUp; +}; + + +class PerspectiveCamera + : public Camera +{ +public: + PerspectiveCamera(); + PerspectiveCamera(const Camera& other); + + basics::Ray PrimaryRay(const int x, const int width, + const int y, const int height) const; + +private: + std::string GetTypeString() const; +}; + + +class OrthographicCamera + : public Camera +{ +public: + OrthographicCamera(); + OrthographicCamera(const Camera& other); + + /** + * Compute a primary ray given an (x,y) coordinate pair. The orthographic + * camera projects rays parallel to the viewing direction through the (x,y) + * coordinate given. Thus, the size of the orthographic camera should be set + * to the size of the view into the scene. + */ + basics::Ray PrimaryRay(const int x, const int width, + const int y, const int height) const; + +private: + std::string GetTypeString() const; +}; + + +std::ostream& operator<<(std::ostream& ost, const Camera& camera); + +} /* namespace charles */ + +#endif