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