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