1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4 
5    This file is part of GtkRadiant.
6 
7    GtkRadiant 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    GtkRadiant 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 GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 #include "qbsp.h"
23 
24 int nummiptex;
25 textureref_t textureref[MAX_MAP_TEXTURES];
26 
27 //==========================================================================
28 
29 
FindMiptex(char * name)30 int FindMiptex( char *name ){
31 	int i;
32 	char path[1024];
33 	miptex_t    *mt;
34 	miptex_m8_t *mt_m8;
35 	miptex_m32_t    *mt_m32;
36 
37 	for ( i = 0 ; i < nummiptex ; i++ )
38 		if ( !strcmp( name, textureref[i].name ) ) {
39 			return i;
40 		}
41 	if ( nummiptex == MAX_MAP_TEXTURES ) {
42 		Error( "MAX_MAP_TEXTURES" );
43 	}
44 	strcpy( textureref[i].name, name );
45 
46 	// load the miptex to get the flags and values
47 	if ( !strcmp( game, "heretic2" ) ) {
48 		sprintf( path, "%stextures/%s.m32", gamedir, name );
49 		if ( TryLoadFile( path, (void **)&mt_m32 ) != -1 ) {
50 			textureref[i].value = LittleLong( mt_m32->value );
51 			textureref[i].flags = LittleLong( mt_m32->flags );
52 			textureref[i].contents = LittleLong( mt_m32->contents );
53 			strcpy( textureref[i].animname, mt_m32->animname );
54 			free( mt_m32 );
55 		}
56 		else{
57 			sprintf( path, "%stextures/%s.m8", gamedir, name );
58 		}
59 
60 		if ( TryLoadFile( path, (void **)&mt_m8 ) != -1 ) {
61 			textureref[i].value = LittleLong( mt_m8->value );
62 			textureref[i].flags = LittleLong( mt_m8->flags );
63 			textureref[i].contents = LittleLong( mt_m8->contents );
64 			strcpy( textureref[i].animname, mt_m8->animname );
65 			free( mt_m8 );
66 		}
67 	}
68 	else
69 	{
70 		sprintf( path, "%stextures/%s.wal", gamedir, name );
71 		if ( TryLoadFile( path, (void **)&mt ) != -1 ) {
72 			textureref[i].value = LittleLong( mt->value );
73 			textureref[i].flags = LittleLong( mt->flags );
74 			textureref[i].contents = LittleLong( mt->contents );
75 			strcpy( textureref[i].animname, mt->animname );
76 			free( mt );
77 		}
78 	}
79 
80 	nummiptex++;
81 
82 	if ( textureref[i].animname[0] ) {
83 		FindMiptex( textureref[i].animname );
84 	}
85 
86 	return i;
87 }
88 
89 
90 /*
91    ==================
92    textureAxisFromPlane
93    ==================
94  */
95 vec3_t baseaxis[18] =
96 {
97 	{0,0,1}, {1,0,0}, {0,-1,0},     // floor
98 	{0,0,-1}, {1,0,0}, {0,-1,0},    // ceiling
99 	{1,0,0}, {0,1,0}, {0,0,-1},     // west wall
100 	{-1,0,0}, {0,1,0}, {0,0,-1},    // east wall
101 	{0,1,0}, {1,0,0}, {0,0,-1},     // south wall
102 	{0,-1,0}, {1,0,0}, {0,0,-1}     // north wall
103 };
104 
TextureAxisFromPlane(plane_t * pln,vec3_t xv,vec3_t yv)105 void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv ){
106 	int bestaxis;
107 	vec_t dot,best;
108 	int i;
109 
110 	best = 0;
111 	bestaxis = 0;
112 
113 	for ( i = 0 ; i < 6 ; i++ )
114 	{
115 		dot = DotProduct( pln->normal, baseaxis[i * 3] );
116 		if ( dot > best ) {
117 			best = dot;
118 			bestaxis = i;
119 		}
120 	}
121 
122 	VectorCopy( baseaxis[bestaxis * 3 + 1], xv );
123 	VectorCopy( baseaxis[bestaxis * 3 + 2], yv );
124 }
125 
126 
127 
128 
TexinfoForBrushTexture(plane_t * plane,brush_texture_t * bt,vec3_t origin)129 int TexinfoForBrushTexture( plane_t *plane, brush_texture_t *bt, vec3_t origin ){
130 	vec3_t vecs[2];
131 	int sv, tv;
132 	vec_t ang, sinv, cosv;
133 	vec_t ns, nt;
134 	texinfo_t tx, *tc;
135 	int i, j, k;
136 	float shift[2];
137 	brush_texture_t anim;
138 	int mt;
139 
140 	if ( !bt->name[0] ) {
141 		return 0;
142 	}
143 
144 	memset( &tx, 0, sizeof( tx ) );
145 	strcpy( tx.texture, bt->name );
146 
147 	TextureAxisFromPlane( plane, vecs[0], vecs[1] );
148 
149 	shift[0] = DotProduct( origin, vecs[0] );
150 	shift[1] = DotProduct( origin, vecs[1] );
151 
152 	if ( !bt->scale[0] ) {
153 		bt->scale[0] = 1;
154 	}
155 	if ( !bt->scale[1] ) {
156 		bt->scale[1] = 1;
157 	}
158 
159 
160 // rotate axis
161 	if ( bt->rotate == 0 ) {
162 		sinv = 0 ; cosv = 1;
163 	}
164 	else if ( bt->rotate == 90 ) {
165 		sinv = 1 ; cosv = 0;
166 	}
167 	else if ( bt->rotate == 180 ) {
168 		sinv = 0 ; cosv = -1;
169 	}
170 	else if ( bt->rotate == 270 ) {
171 		sinv = -1 ; cosv = 0;
172 	}
173 	else
174 	{
175 		ang = bt->rotate / 180 * Q_PI;
176 		sinv = sin( ang );
177 		cosv = cos( ang );
178 	}
179 
180 	if ( vecs[0][0] ) {
181 		sv = 0;
182 	}
183 	else if ( vecs[0][1] ) {
184 		sv = 1;
185 	}
186 	else{
187 		sv = 2;
188 	}
189 
190 	if ( vecs[1][0] ) {
191 		tv = 0;
192 	}
193 	else if ( vecs[1][1] ) {
194 		tv = 1;
195 	}
196 	else{
197 		tv = 2;
198 	}
199 
200 	for ( i = 0 ; i < 2 ; i++ )
201 	{
202 		ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
203 		nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
204 		vecs[i][sv] = ns;
205 		vecs[i][tv] = nt;
206 	}
207 
208 	for ( i = 0 ; i < 2 ; i++ )
209 		for ( j = 0 ; j < 3 ; j++ )
210 			tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
211 
212 	tx.vecs[0][3] = bt->shift[0] + shift[0];
213 	tx.vecs[1][3] = bt->shift[1] + shift[1];
214 	tx.flags = bt->flags;
215 	tx.value = bt->value;
216 
217 	//
218 	// find the texinfo
219 	//
220 	tc = texinfo;
221 	for ( i = 0 ; i < numtexinfo ; i++, tc++ )
222 	{
223 		if ( tc->flags != tx.flags ) {
224 			continue;
225 		}
226 		if ( tc->value != tx.value ) {
227 			continue;
228 		}
229 		for ( j = 0 ; j < 2 ; j++ )
230 		{
231 			if ( strcmp( tc->texture, tx.texture ) ) {
232 				goto skip;
233 			}
234 			for ( k = 0 ; k < 4 ; k++ )
235 			{
236 				if ( tc->vecs[j][k] != tx.vecs[j][k] ) {
237 					goto skip;
238 				}
239 			}
240 		}
241 		return i;
242 skip:;
243 	}
244 	*tc = tx;
245 	numtexinfo++;
246 
247 	// load the next animation
248 	mt = FindMiptex( bt->name );
249 	if ( textureref[mt].animname[0] ) {
250 		anim = *bt;
251 		strcpy( anim.name, textureref[mt].animname );
252 		tc->nexttexinfo = TexinfoForBrushTexture( plane, &anim, origin );
253 	}
254 	else{
255 		tc->nexttexinfo = -1;
256 	}
257 
258 
259 	return i;
260 }
261