]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/q2map/textures.c
Merge branch 'nomagicpath' into 'master'
[xonotic/netradiant.git] / tools / quake2 / q2map / textures.c
1 /*
2    Copyright (C) 1999-2007 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
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
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
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 }