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