![]() |
Kukatz 3D
0.1
Török Attila szakdolgozata
|
00001 /* 00002 * camera.cpp - Kukatz 3D 00003 * Copyright (c) 2010, 2011 - TÖRÖK Attila (torokati44@gmail.com) 00004 * 00005 * This software is provided 'as-is', without any express or implied 00006 * warranty. In no event will the authors be held liable for any damages 00007 * arising from the use of this software. 00008 * 00009 * Permission is granted to anyone to use this software for any purpose, 00010 * including commercial applications, and to alter it and redistribute it 00011 * freely, subject to the following restrictions: 00012 * 00013 * 1. The origin of this software must not be misrepresented; you must not 00014 * claim that you wrote the original software. If you use this software 00015 * in a product, an acknowledgment in the product documentation would be 00016 * appreciated but is not required. 00017 * 00018 * 2. Altered source versions must be plainly marked as such, and must not be 00019 * misrepresented as being the original software. 00020 * 00021 * 3. This notice may not be removed or altered from any source 00022 * distribution. 00023 */ 00024 00025 #include "camera.hpp" 00026 00027 #include "followercamera.hpp" 00028 00029 #include <iostream> 00030 00031 #include "opengl.hpp" 00032 #include "misc.hpp" 00033 00034 //unsigned long int Camera::culled[7]; 00035 Camera* Camera::current_cam = 0; 00036 00037 Camera::Camera(const sf::Vector3f& p, const sf::Vector3f& c, 00038 const sf::Vector3f& u, const sf::Vector2i& offs, const sf::Vector2i& s, 00039 float f, float zn, float zf): 00040 Viewport(offs, s, zn, zf), 00041 pos(p), center(c), up(u), 00042 object(new StaticObject("CAMERA", "ATLAS_1")), 00043 fov(f), eye_distance(0.05f), screen_distance(5.0f) 00044 { 00045 update_object(); 00046 /* 00047 for (unsigned int i = 0; i < 7; ++i) 00048 { 00049 culled[i] = 0; 00050 } 00051 */ 00052 current_cam = this; 00053 get_corners(0.0f); 00054 } 00055 00056 void Camera::update_object() 00057 { 00058 object->set_position(pos); 00059 00060 object->set_x_axis(normalize(center - pos)); 00061 object->set_y_axis(normalize(crossprod(up, center - pos))); 00062 object->set_z_axis(); 00063 } 00064 00065 /* 00066 void Camera::get_matrices() 00067 { 00068 glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix); 00069 glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix); 00070 glGetIntegerv(GL_VIEWPORT, viewport); 00071 } 00072 */ 00073 00074 void Camera::get_corners(float d) 00075 { 00076 float near_half_height = z_near * tan(fov * 0.5f * M_PI / 180.0f); 00077 float near_half_width = near_half_height * (float)size.x / (float)size.y; 00078 00079 float far_half_height = z_far * tan(fov * 0.5f * M_PI / 180.0f); 00080 float far_half_width = far_half_height * (float)size.x / (float)size.y; 00081 00082 sf::Vector3f forward_normal = normalize(center - pos); 00083 sf::Vector3f left = normalize(crossprod(up, forward_normal)); 00084 sf::Vector3f up = normalize(crossprod(-left, forward_normal)); 00085 00086 00087 bln = pos + forward_normal * z_near + left * (near_half_width - d * (eye_distance / 2.0f) * (z_near / screen_distance)) - up * near_half_height; 00088 blf = pos + forward_normal * z_far + left * (far_half_width - d * (eye_distance / 2.0f) * (z_far / screen_distance)) - up * far_half_height; 00089 brn = pos + forward_normal * z_near - left * (near_half_width + d * (eye_distance / 2.0f) * (z_near / screen_distance)) - up * near_half_height; 00090 brf = pos + forward_normal * z_far - left * (far_half_width + d * (eye_distance / 2.0f) * (z_far / screen_distance)) - up * far_half_height; 00091 00092 tln = pos + forward_normal * z_near + left * (near_half_width - d * (eye_distance / 2.0f) * (z_near / screen_distance)) + up * near_half_height; 00093 tlf = pos + forward_normal * z_far + left * (far_half_width - d * (eye_distance / 2.0f) * (z_far / screen_distance)) + up * far_half_height; 00094 trn = pos + forward_normal * z_near - left * (near_half_width + d * (eye_distance / 2.0f) * (z_near / screen_distance)) + up * near_half_height; 00095 trf = pos + forward_normal * z_far - left * (far_half_width + d * (eye_distance / 2.0f) * (z_far / screen_distance)) + up * far_half_height; 00096 } 00097 00098 void Camera::get_planes() 00099 { 00100 sf::Vector3f forward_normal = normalize(center - pos); 00101 sf::Vector3f bottom_normal = normalize(crossprod(brn - bln, blf - bln)); 00102 sf::Vector3f left_normal = normalize(crossprod(blf - bln, tln - bln)); 00103 sf::Vector3f top_normal = normalize(crossprod(tln - trn, trf - trn)); 00104 sf::Vector3f right_normal = normalize(crossprod(trn - brn, brf - brn)); 00105 00106 //BOTTOM 00107 planes[0].point = bln; 00108 planes[0].normal = bottom_normal; 00109 00110 //NEAR 00111 planes[1].point = bln; 00112 planes[1].normal = forward_normal; 00113 00114 //LEFT 00115 planes[2].point = bln; 00116 planes[2].normal = left_normal; 00117 00118 //RIGHT 00119 planes[3].point = brn; 00120 planes[3].normal = right_normal; 00121 00122 //TOP 00123 planes[4].point = tln; 00124 planes[4].normal = top_normal; 00125 00126 //FAR 00127 planes[5].point = blf; 00128 planes[5].normal = -forward_normal; 00129 00130 //bln += up * 0.001f; 00131 /* 00132 glPointSize(20.0); 00133 Texture::unbind(); 00134 glColor4ub(255,0, 0, 255); 00135 glBegin(GL_POINTS); 00136 glVertex3f(bln.x, bln.y, bln.z); 00137 bln += bottom_normal * 0.1f; 00138 glVertex3f(bln.x, bln.y, bln.z); 00139 glEnd(); 00140 glColor4ub(255, 255, 255, 255);*/ 00141 } 00142 00143 void Camera::render() 00144 { 00145 object->render(); 00146 00147 Texture::unbind(); 00148 00149 #define VERTEX(P) glVertex3f((P).x, (P).y, (P).z); 00150 00151 glBegin(GL_LINES); 00152 00153 VERTEX(bln); 00154 VERTEX(brn); 00155 00156 VERTEX(tln); 00157 VERTEX(trn); 00158 00159 VERTEX(bln); 00160 VERTEX(tln); 00161 00162 VERTEX(brn); 00163 VERTEX(trn); 00164 00165 VERTEX(bln); 00166 VERTEX(blf); 00167 00168 VERTEX(brn); 00169 VERTEX(brf); 00170 00171 VERTEX(tln); 00172 VERTEX(tlf); 00173 00174 VERTEX(trn); 00175 VERTEX(trf); 00176 00177 glEnd(); 00178 } 00179 00180 void Camera::set_pos(const sf::Vector3f& p, const sf::Vector3f& c, 00181 const sf::Vector3f& u) 00182 { 00183 pos = p; 00184 center = c; 00185 up = u; 00186 } 00187 00188 00189 const sf::Vector3f& Camera::get_pos() 00190 { 00191 return pos; 00192 } 00193 00194 const sf::Vector3f& Camera::get_center() 00195 { 00196 return center; 00197 } 00198 00199 const sf::Vector3f& Camera::get_up() 00200 { 00201 return up; 00202 } 00203 00204 Camera& Camera::get_current() 00205 { 00206 return *current_cam; 00207 } 00208 00209 bool Camera::sees(const sf::Vector3f& p, float r) 00210 { 00211 for (unsigned int i = 0; i < 6; ++i) 00212 { 00213 if (dotprod(planes[i].normal, normalize((p + planes[i].normal * r) - planes[i].point)) < 0) 00214 { 00215 //++culled[i]; 00216 return false; 00217 } 00218 } 00219 00220 //++culled[6]; 00221 00222 return true; 00223 } 00224 00225 void Camera::look_3d(float d) 00226 { 00227 glMatrixMode(GL_PROJECTION); 00228 glLoadIdentity(); 00229 00230 float half_height = z_near * tan(fov * 0.5f * M_PI / 180.f); 00231 float half_width = half_height * (float)size.x / (float) size.y; 00232 00233 glFrustum(-half_width - d * ((eye_distance / 2.0f) * (z_near / screen_distance)), 00234 half_width - d * ((eye_distance / 2.0f) * (z_near / screen_distance)), 00235 -half_height, half_height, z_near, z_far); 00236 00237 glMatrixMode(GL_MODELVIEW); 00238 glLoadIdentity(); 00239 00240 sf::Vector3f right = normalize(crossprod(center - pos, up)) / 2.0f; 00241 // eye distance is halved by the coefficient above... so it's a half-normal 00242 00243 gluLookAt( 00244 pos.x + right.x * eye_distance * d, 00245 pos.y + right.y * eye_distance * d, 00246 pos.z + right.z * eye_distance * d, 00247 00248 center.x + right.x * eye_distance * d, 00249 center.y + right.y * eye_distance * d, 00250 center.z + right.z * eye_distance * d, 00251 00252 up.x, up.y, up.z); 00253 00254 glViewport(offset.x, offset.y, size.x, size.y); 00255 00256 current_cam = this; 00257 00258 get_corners(d); 00259 get_planes(); 00260 } 00261 00262 Camera::~Camera() 00263 { 00264 /* 00265 for (unsigned int i = 0; i < 7; ++i) 00266 { 00267 std::cout << i << ".: " << culled[i] << "\n"; 00268 } 00269 */ 00270 delete object; 00271 }