1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 //
21 // r_math.c
22 // Renderer math library
23 //
24
25 #include "r_local.h"
26
27 /*
28 =============
29 R_SetupProjectionMatrix
30 =============
31 */
R_CalcZFar(void)32 static inline float R_CalcZFar (void)
33 {
34 float forwardDist, viewDist;
35 float forwardClip;
36 float skySize;
37 int i;
38
39 if (ri.scn.worldModel->type == MODEL_Q3BSP) {
40 // FIXME: adjust for skydome height * 2!
41 skySize = SKY_BOXSIZE * 2;
42 }
43 else {
44 // FIXME: make this dependant on if there's a skybox or not
45 skySize = SKY_BOXSIZE * 2;
46 }
47
48 forwardDist = DotProduct (ri.def.viewOrigin, ri.def.viewAxis[0]);
49 forwardClip = skySize + forwardDist;
50
51 viewDist = 0;
52 for (i=0 ; i<3 ; i++) {
53 if (ri.def.viewAxis[0][i] < 0)
54 viewDist += ri.scn.worldModel->bspModel.nodes[0].c.mins[i] * ri.def.viewAxis[0][i];
55 else
56 viewDist += ri.scn.worldModel->bspModel.nodes[0].c.maxs[i] * ri.def.viewAxis[0][i];
57 }
58 if (viewDist > forwardClip)
59 forwardClip = viewDist;
60
61 // Bias by 256 pixels
62 return max (forwardClip - forwardDist + 256, ri.scn.zFar);
63 }
R_SetupProjectionMatrix(refDef_t * rd,mat4x4_t m)64 void R_SetupProjectionMatrix (refDef_t *rd, mat4x4_t m)
65 {
66 GLfloat xMin, xMax;
67 GLfloat yMin, yMax;
68 GLfloat zNear;
69 GLfloat vAspect = (float)rd->width/(float)rd->height;
70
71 // Near/far clip
72 zNear = r_zNear->intVal;
73 if (r_zFarAbs->intVal) {
74 ri.scn.zFar = r_zFarAbs->intVal;
75 }
76 else {
77 if (ri.def.rdFlags & RDF_NOWORLDMODEL)
78 ri.scn.zFar = 2048;
79 else
80 ri.scn.zFar = r_zFarMin->intVal + R_CalcZFar ();
81 }
82
83 // Calculate aspect
84 yMax = zNear * (float)tan ((rd->fovY * M_PI) / 360.0f);
85 yMin = -yMax;
86
87 xMin = yMin * vAspect;
88 xMax = yMax * vAspect;
89
90 xMin += -(2 * ri.cameraSeparation) / zNear;
91 xMax += -(2 * ri.cameraSeparation) / zNear;
92
93 // Apply to matrix
94 m[0] = (2.0f * zNear) / (xMax - xMin);
95 m[1] = 0.0f;
96 m[2] = 0.0f;
97 m[3] = 0.0f;
98 m[4] = 0.0f;
99 m[5] = (2.0f * zNear) / (yMax - yMin);
100 m[6] = 0.0f;
101 m[7] = 0.0f;
102 m[8] = (xMax + xMin) / (xMax - xMin);
103 m[9] = (yMax + yMin) / (yMax - yMin);
104 m[10] = -(ri.scn.zFar + zNear) / (ri.scn.zFar - zNear);
105 m[11] = -1.0f;
106 m[12] = 0.0f;
107 m[13] = 0.0f;
108 m[14] = -(2.0f * ri.scn.zFar * zNear) / (ri.scn.zFar - zNear);
109 m[15] = 0.0f;
110 }
111
112
113 /*
114 =============
115 R_SetupModelviewMatrix
116 =============
117 */
R_SetupModelviewMatrix(refDef_t * rd,mat4x4_t m)118 void R_SetupModelviewMatrix (refDef_t *rd, mat4x4_t m)
119 {
120 #if 0
121 Matrix4_Identity (m);
122 Matrix4_Rotate (m, -90, 1, 0, 0);
123 Matrix4_Rotate (m, 90, 0, 0, 1);
124 #else
125 Vec4Set (&m[0], 0, 0, -1, 0);
126 Vec4Set (&m[4], -1, 0, 0, 0);
127 Vec4Set (&m[8], 0, 1, 0, 0);
128 Vec4Set (&m[12], 0, 0, 0, 1);
129 #endif
130
131 Matrix4_Rotate (m, -rd->viewAngles[2], 1, 0, 0);
132 Matrix4_Rotate (m, -rd->viewAngles[0], 0, 1, 0);
133 Matrix4_Rotate (m, -rd->viewAngles[1], 0, 0, 1);
134 Matrix4_Translate (m, -rd->viewOrigin[0], -rd->viewOrigin[1], -rd->viewOrigin[2]);
135 }
136
137
138 /*
139 ===============
140 Matrix4_Multiply_Vector
141 ===============
142 */
Matrix4_Multiply_Vector(const mat4x4_t m,const vec4_t v,vec4_t out)143 void Matrix4_Multiply_Vector (const mat4x4_t m, const vec4_t v, vec4_t out)
144 {
145 out[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];
146 out[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];
147 out[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];
148 out[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];
149 }
150