/* ================================================================ RenderCamera ---------------- This header file defines the RenderCamera class. ================================================================ */ #include "RenderCamera.hpp" #include "Log.hpp" #include // fminf, M_PI #define PI 3.1415926535897932384626433832795 #define PI_OVER_180 0.017453292519943295769236907684886 #define PI_OVER_360 0.0087266462599716478846184538424431 #ifndef fminf // Just for the winderps #define fminf(a,b) (a) < (b) ? (a) : (b) #endif /* ======== Constructors and Destructors ======== */ RenderCamera::RenderCamera() { fov_angle = M_PI / 4.0f; size = 40.0f; // Default orthogonal size of 40 meters, vertically near = 0.1f; far = 512.0f; pitch = yaw = 0; render_mode = 0; flags = 0; width = height = 1; render_view = NULL; } RenderCamera::~RenderCamera() { } /* ======== Update functions ======== */ void RenderCamera::updateProjection(int width_, int height_) { width = width_; height = height_; GLfloat wf = (GLfloat)width; GLfloat hf = (GLfloat)height; GLfloat aspect = wf/hf; if (render_mode == 0) { float y = 1.0f / tan((fov_angle)/2.0f); float x = (1/(aspect))*y; p_matrix[0] = Vec4(x, 0.0f, 0.0f, 0.0f); p_matrix[1] = Vec4(0.0f, y, 0.0f, 0.0f); p_matrix[2] = Vec4(0.0f, 0.0f, far/(far-near), 1.0f); p_matrix[3] = Vec4(0.0f, 0.0f, -((far*near)/(far-near)), 0.0f); } else { float x = size * aspect; float y = size; p_matrix[0] = Vec4(2.0f / x, 0.0f, 0.0f, 0.0f); p_matrix[1] = Vec4(0.0f, 2.0f / y, 0.0f, 0.0f); p_matrix[2] = Vec4(0.0f, 0.0f, 1.0f/(far-near), 0.0f); p_matrix[3] = Vec4(0.0f, 0.0f, -near/(far-near), 1.0f); } } void RenderCamera::doRefresh() { if (!(flags & DIRTY)) return; float c_p = cos(pitch * M_PI / 180.0f); float s_p = sin(pitch * M_PI / 180.0f); float c_y = cos(yaw * M_PI / 180.0f); float s_y = sin(yaw * M_PI / 180.0f); Vec3 x(c_y, 0, -s_y); Vec3 y(s_y*s_p, c_p, c_y * s_p); Vec3 z(s_y * c_p, -s_p, c_p * c_y); mv_matrix = Mat4( Vec4(x.x, y.x, z.x, 0.0f), Vec4(x.y, y.y, z.y, 0.0f), Vec4(x.z, y.z, z.z, 0.0f), Vec4(-x.dotProduct(position), -y.dotProduct(position), -z.dotProduct(position), 1.0f) ); flags &= ~DIRTY; } /* ======== Setter functions ======== */ // sets to orthogonal or perspective rendering void RenderCamera::setRenderMode(int mode) { if (mode == 1) { render_mode = mode; } else { render_mode = 0; } updateProjection(width, height); } int RenderCamera::setRenderView(RenderView *rv) { if (rv == NULL) return 1; render_view = rv; return 0; } void RenderCamera::setPosition(float x, float y, float z) { position.x = x; position.y = y; position.z = z; flags |= DIRTY; } void RenderCamera::setPitch(float pitch_) { pitch = pitch_; flags |= DIRTY; } void RenderCamera::setYaw(float yaw_) { yaw = yaw_; flags |= DIRTY; } /* ======== Getter functions ======== */ RenderView* RenderCamera::getRenderView() { return render_view; } Vec3 RenderCamera::getPosition() { return position; } float RenderCamera::getYaw() { return yaw; } float RenderCamera::getPitch() { return pitch; } float RenderCamera::getSize() { return size; } Mat4 RenderCamera::getModelview() { return mv_matrix; } int RenderCamera::getRenderMode() { return render_mode; }