1 /* 2 Copyright (C) 2003, 2010 - Wolfire Games 3 Copyright (C) 2010-2017 - Lugaru contributors (see AUTHORS file) 4 5 This file is part of Lugaru. 6 7 Lugaru is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 Lugaru is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Lugaru. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "Math/Frustum.hpp" 22 23 #include "Graphic/gamegl.hpp" 24 25 #include <math.h> 26 27 void FRUSTUM:: GetFrustum()28 GetFrustum() 29 { 30 static float projmatrix[16]; 31 static float mvmatrix[16]; 32 static float clip[16]; 33 34 glGetFloatv(GL_PROJECTION_MATRIX, projmatrix); 35 glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix); 36 37 // Combine the matrices 38 clip[0] = mvmatrix[0] * projmatrix[0] + mvmatrix[1] * projmatrix[4] + mvmatrix[2] * projmatrix[8] + mvmatrix[3] * projmatrix[12]; 39 clip[1] = mvmatrix[0] * projmatrix[1] + mvmatrix[1] * projmatrix[5] + mvmatrix[2] * projmatrix[9] + mvmatrix[3] * projmatrix[13]; 40 clip[2] = mvmatrix[0] * projmatrix[2] + mvmatrix[1] * projmatrix[6] + mvmatrix[2] * projmatrix[10] + mvmatrix[3] * projmatrix[14]; 41 clip[3] = mvmatrix[0] * projmatrix[3] + mvmatrix[1] * projmatrix[7] + mvmatrix[2] * projmatrix[11] + mvmatrix[3] * projmatrix[15]; 42 43 clip[4] = mvmatrix[4] * projmatrix[0] + mvmatrix[5] * projmatrix[4] + mvmatrix[6] * projmatrix[8] + mvmatrix[7] * projmatrix[12]; 44 clip[5] = mvmatrix[4] * projmatrix[1] + mvmatrix[5] * projmatrix[5] + mvmatrix[6] * projmatrix[9] + mvmatrix[7] * projmatrix[13]; 45 clip[6] = mvmatrix[4] * projmatrix[2] + mvmatrix[5] * projmatrix[6] + mvmatrix[6] * projmatrix[10] + mvmatrix[7] * projmatrix[14]; 46 clip[7] = mvmatrix[4] * projmatrix[3] + mvmatrix[5] * projmatrix[7] + mvmatrix[6] * projmatrix[11] + mvmatrix[7] * projmatrix[15]; 47 48 clip[8] = mvmatrix[8] * projmatrix[0] + mvmatrix[9] * projmatrix[4] + mvmatrix[10] * projmatrix[8] + mvmatrix[11] * projmatrix[12]; 49 clip[9] = mvmatrix[8] * projmatrix[1] + mvmatrix[9] * projmatrix[5] + mvmatrix[10] * projmatrix[9] + mvmatrix[11] * projmatrix[13]; 50 clip[10] = mvmatrix[8] * projmatrix[2] + mvmatrix[9] * projmatrix[6] + mvmatrix[10] * projmatrix[10] + mvmatrix[11] * projmatrix[14]; 51 clip[11] = mvmatrix[8] * projmatrix[3] + mvmatrix[9] * projmatrix[7] + mvmatrix[10] * projmatrix[11] + mvmatrix[11] * projmatrix[15]; 52 53 clip[12] = mvmatrix[12] * projmatrix[0] + mvmatrix[13] * projmatrix[4] + mvmatrix[14] * projmatrix[8] + mvmatrix[15] * projmatrix[12]; 54 clip[13] = mvmatrix[12] * projmatrix[1] + mvmatrix[13] * projmatrix[5] + mvmatrix[14] * projmatrix[9] + mvmatrix[15] * projmatrix[13]; 55 clip[14] = mvmatrix[12] * projmatrix[2] + mvmatrix[13] * projmatrix[6] + mvmatrix[14] * projmatrix[10] + mvmatrix[15] * projmatrix[14]; 56 clip[15] = mvmatrix[12] * projmatrix[3] + mvmatrix[13] * projmatrix[7] + mvmatrix[14] * projmatrix[11] + mvmatrix[15] * projmatrix[15]; 57 58 // Right plane 59 frustum[0][0] = clip[3] - clip[0]; 60 frustum[0][1] = clip[7] - clip[4]; 61 frustum[0][2] = clip[11] - clip[8]; 62 frustum[0][3] = clip[15] - clip[12]; 63 64 // Left plane 65 frustum[1][0] = clip[3] + clip[0]; 66 frustum[1][1] = clip[7] + clip[4]; 67 frustum[1][2] = clip[11] + clip[8]; 68 frustum[1][3] = clip[15] + clip[12]; 69 70 // Bottom plane 71 frustum[2][0] = clip[3] + clip[1]; 72 frustum[2][1] = clip[7] + clip[5]; 73 frustum[2][2] = clip[11] + clip[9]; 74 frustum[2][3] = clip[15] + clip[13]; 75 76 // Top plane 77 frustum[3][0] = clip[3] - clip[1]; 78 frustum[3][1] = clip[7] - clip[5]; 79 frustum[3][2] = clip[11] - clip[9]; 80 frustum[3][3] = clip[15] - clip[13]; 81 82 // Far plane 83 frustum[4][0] = clip[3] - clip[2]; 84 frustum[4][1] = clip[7] - clip[6]; 85 frustum[4][2] = clip[11] - clip[10]; 86 frustum[4][3] = clip[15] - clip[14]; 87 88 // Near plane 89 frustum[5][0] = clip[3] + clip[2]; 90 frustum[5][1] = clip[7] + clip[6]; 91 frustum[5][2] = clip[11] + clip[10]; 92 frustum[5][3] = clip[15] + clip[14]; 93 } 94 95 int FRUSTUM:: CubeInFrustum(float x,float y,float z,float size)96 CubeInFrustum(float x, float y, float z, float size) 97 { 98 static int c, c2; 99 100 for (int i = 0; i < 6; i++) { 101 c = 0; 102 if (frustum[i][0] * (x - size) + frustum[i][1] * (y - size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 103 c++; 104 } 105 if (frustum[i][0] * (x + size) + frustum[i][1] * (y - size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 106 c++; 107 } 108 if (frustum[i][0] * (x - size) + frustum[i][1] * (y + size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 109 c++; 110 } 111 if (frustum[i][0] * (x + size) + frustum[i][1] * (y + size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 112 c++; 113 } 114 if (frustum[i][0] * (x - size) + frustum[i][1] * (y - size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 115 c++; 116 } 117 if (frustum[i][0] * (x + size) + frustum[i][1] * (y - size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 118 c++; 119 } 120 if (frustum[i][0] * (x - size) + frustum[i][1] * (y + size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 121 c++; 122 } 123 if (frustum[i][0] * (x + size) + frustum[i][1] * (y + size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 124 c++; 125 } 126 if (c == 0) { 127 return 0; 128 } 129 if (c == 8) { 130 c2++; 131 } 132 } 133 if (c2 >= 6) { 134 return 2; 135 } else { 136 return 1; 137 } 138 } 139 140 int FRUSTUM:: CubeInFrustum(float x,float y,float z,float size,float height)141 CubeInFrustum(float x, float y, float z, float size, float height) 142 { 143 static int c, c2; 144 145 for (int i = 0; i < 6; i++) { 146 c = 0; 147 if (frustum[i][0] * (x - size) + frustum[i][1] * (y - height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 148 c++; 149 } 150 if (frustum[i][0] * (x + size) + frustum[i][1] * (y - height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 151 c++; 152 } 153 if (frustum[i][0] * (x - size) + frustum[i][1] * (y + height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 154 c++; 155 } 156 if (frustum[i][0] * (x + size) + frustum[i][1] * (y + height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) { 157 c++; 158 } 159 if (frustum[i][0] * (x - size) + frustum[i][1] * (y - height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 160 c++; 161 } 162 if (frustum[i][0] * (x + size) + frustum[i][1] * (y - height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 163 c++; 164 } 165 if (frustum[i][0] * (x - size) + frustum[i][1] * (y + height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 166 c++; 167 } 168 if (frustum[i][0] * (x + size) + frustum[i][1] * (y + height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) { 169 c++; 170 } 171 if (c == 0) { 172 return 0; 173 } 174 if (c == 8) { 175 c2++; 176 } 177 } 178 if (c2 >= 6) { 179 return 2; 180 } else { 181 return 1; 182 } 183 } 184 185 int FRUSTUM:: SphereInFrustum(float x,float y,float z,float radius)186 SphereInFrustum(float x, float y, float z, float radius) 187 { 188 static int c2; 189 190 for (int i = 0; i < 6; i++) { 191 if (frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] > -1 * radius) { 192 c2++; 193 } else { 194 return 0; 195 } 196 } 197 if (c2 >= 6) { 198 return 2; 199 } else { 200 return 1; 201 } 202 } 203