camera.c (5118B)
1 #include "camera.h" 2 3 #include <math.h> 4 #include <stdlib.h> 5 6 Camera *Camera_make(Transform *t) 7 { 8 Camera *camera = malloc(sizeof *camera); 9 camera->transform = t; 10 Camera_defaultSettings(camera); 11 Camera_updateMatrix(camera); 12 Camera_updateFrustum(camera); 13 return camera; 14 } 15 16 void Camera_free(Camera *camera) 17 { 18 if (camera) 19 { 20 free(camera); 21 } 22 } 23 24 void Camera_defaultSettings(Camera* camera) 25 { 26 camera->fovy = 90.0f; 27 camera->aspect = 1.0f; 28 camera->near = 0.1f; 29 camera->far = 200.0f; 30 31 camera->near_h = 2 * tan(camera->fovy / 2) * camera->near; 32 camera->near_w = camera->near_h * camera->aspect; 33 34 camera->far_h = 2 * tan(camera->fovy / 2) * camera->far; 35 camera->far_w = camera->far_h * camera->aspect; 36 } 37 38 void Camera_updateMatrix(Camera *camera) 39 { 40 Vec3 camera_target; 41 Vec3_add( 42 camera->transform->position, 43 camera->transform->forward, 44 camera_target 45 ); 46 47 Mat4 view; 48 Mat4_lookAt( 49 camera->transform->position, 50 camera_target, 51 camera->transform->up, 52 view 53 ); 54 55 Mat4 projection; 56 Mat4_perspective( 57 radians(camera->fovy), 58 camera->aspect, 59 camera->near, 60 camera->far, 61 projection 62 ); 63 64 Mat4_mul(projection, view, camera->matrix); 65 } 66 67 void Camera_updateFrustum(Camera *camera) 68 { 69 // Near plane 70 camera->frustum[0].n[0] = camera->transform->forward[0]; 71 camera->frustum[0].n[1] = camera->transform->forward[1]; 72 camera->frustum[0].n[2] = camera->transform->forward[2]; 73 Vec3_scale( 74 camera->transform->forward, 75 camera->near, 76 camera->frustum[0].p 77 ); 78 Vec3_add( 79 camera->transform->position, 80 camera->frustum[0].p, 81 camera->frustum[0].p 82 ); 83 84 // Far plane 85 camera->frustum[1].n[0] = -camera->transform->forward[0]; 86 camera->frustum[1].n[1] = -camera->transform->forward[1]; 87 camera->frustum[1].n[2] = -camera->transform->forward[2]; 88 Vec3_scale( 89 camera->transform->forward, 90 camera->far, 91 camera->frustum[1].p 92 ); 93 Vec3_add( 94 camera->transform->position, 95 camera->frustum[1].p, 96 camera->frustum[1].p 97 ); 98 99 // Used to store vector in plane 100 Vec3 a; 101 102 // Top plane 103 Vec3_scale( 104 camera->transform->up, 105 camera->near_h / 2, 106 camera->frustum[2].p 107 ); 108 Vec3_add( 109 camera->frustum[0].p, 110 camera->frustum[2].p, 111 camera->frustum[2].p 112 ); 113 114 Vec3_sub( 115 camera->frustum[2].p, 116 camera->transform->position, 117 a 118 ); 119 120 Vec3_mul( 121 a, 122 camera->transform->right, 123 camera->frustum[2].n 124 ); 125 Vec3_normalize( 126 camera->frustum[2].n, 127 camera->frustum[2].n 128 ); 129 130 // Bottom plane 131 Vec3_scale( 132 camera->transform->up, 133 camera->near_h / 2, 134 camera->frustum[3].p 135 ); 136 Vec3_sub( 137 camera->frustum[0].p, 138 camera->frustum[3].p, 139 camera->frustum[3].p 140 ); 141 142 Vec3_sub( 143 camera->frustum[3].p, 144 camera->transform->position, 145 a 146 ); 147 148 Vec3_mul( 149 camera->transform->right, 150 a, 151 camera->frustum[3].n 152 ); 153 Vec3_normalize( 154 camera->frustum[3].n, 155 camera->frustum[3].n 156 ); 157 158 // Left plane 159 Vec3_scale( 160 camera->transform->right, 161 camera->near_w / 2, 162 camera->frustum[4].p 163 ); 164 Vec3_sub( 165 camera->frustum[0].p, 166 camera->frustum[4].p, 167 camera->frustum[4].p 168 ); 169 170 Vec3_sub( 171 camera->frustum[4].p, 172 camera->transform->position, 173 a 174 ); 175 176 Vec3_mul( 177 a, 178 camera->transform->up, 179 camera->frustum[4].n 180 ); 181 Vec3_normalize( 182 camera->frustum[4].n, 183 camera->frustum[4].n 184 ); 185 186 // Right plane 187 Vec3_scale( 188 camera->transform->right, 189 camera->near_w / 2, 190 camera->frustum[5].p 191 ); 192 Vec3_add( 193 camera->frustum[0].p, 194 camera->frustum[5].p, 195 camera->frustum[5].p 196 ); 197 198 Vec3_sub( 199 camera->frustum[5].p, 200 camera->transform->position, 201 a 202 ); 203 204 Vec3_mul( 205 camera->transform->up, 206 a, 207 camera->frustum[5].n 208 ); 209 Vec3_normalize( 210 camera->frustum[5].n, 211 camera->frustum[5].n 212 ); 213 214 } 215 216 static f32 planeSDF(const Plane *p, const Vec3 r) 217 { 218 return Vec3_dot(p->n, r) - Vec3_dot(p->n, p->p); 219 } 220 221 b8 Camera_sphereInFrustum(const Camera *camera, Vec3 p, f32 r) 222 { 223 for (i32 i = 0; i < 6; i++) 224 { 225 f32 distance = planeSDF(&camera->frustum[i], p); 226 if (distance < -r) 227 { 228 return false; 229 } 230 else if (distance < r) 231 { 232 return true; 233 } 234 } 235 return true; 236 } 237