]> git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/bsp/qbsp3/textures.c
Q2Tools source - didn't import this in initially
[xonotic/netradiant.git] / tools / quake2 / extra / bsp / qbsp3 / textures.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, 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 Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 #include "qbsp.h"
24
25 int             nummiptex;
26 textureref_t    textureref[MAX_MAP_TEXTURES];
27
28 //==========================================================================
29
30
31 int     FindMiptex (char *name)
32 {
33         int             i;
34         char    path[1024];
35         miptex_t        *mt;
36
37         for (i=0 ; i<nummiptex ; i++)
38                 if (!strcmp (name, textureref[i].name))
39                 {
40                         return i;
41                 }
42         if (nummiptex == MAX_MAP_TEXTURES)
43                 Error ("MAX_MAP_TEXTURES");
44         strcpy (textureref[i].name, name);
45
46         // load the miptex to get the flags and values
47         sprintf (path, "%stextures/%s.wal", gamedir, name);
48         if (TryLoadFile (path, (void **)&mt) != -1)
49         {
50                 textureref[i].value = LittleLong (mt->value);
51                 textureref[i].flags = LittleLong (mt->flags);
52                 textureref[i].contents = LittleLong (mt->contents);
53                 strcpy (textureref[i].animname, mt->animname);
54                 free (mt);
55         }
56         nummiptex++;
57
58         if (textureref[i].animname[0])
59                 FindMiptex (textureref[i].animname);
60
61         return i;
62 }
63
64
65 /*
66 ==================
67 textureAxisFromPlane
68 ==================
69 */
70 vec3_t  baseaxis[18] =
71 {
72 {0,0,1}, {1,0,0}, {0,-1,0},                     // floor
73 {0,0,-1}, {1,0,0}, {0,-1,0},            // ceiling
74 {1,0,0}, {0,1,0}, {0,0,-1},                     // west wall
75 {-1,0,0}, {0,1,0}, {0,0,-1},            // east wall
76 {0,1,0}, {1,0,0}, {0,0,-1},                     // south wall
77 {0,-1,0}, {1,0,0}, {0,0,-1}                     // north wall
78 };
79
80 void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
81 {
82         int             bestaxis;
83         vec_t   dot,best;
84         int             i;
85         
86         best = 0;
87         bestaxis = 0;
88         
89         for (i=0 ; i<6 ; i++)
90         {
91                 dot = DotProduct (pln->normal, baseaxis[i*3]);
92                 if (dot > best)
93                 {
94                         best = dot;
95                         bestaxis = i;
96                 }
97         }
98         
99         VectorCopy (baseaxis[bestaxis*3+1], xv);
100         VectorCopy (baseaxis[bestaxis*3+2], yv);
101 }
102
103
104
105
106 int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin)
107 {
108         vec3_t  vecs[2];
109         int             sv, tv;
110         vec_t   ang, sinv, cosv;
111         vec_t   ns, nt;
112         texinfo_t       tx, *tc;
113         int             i, j, k;
114         float   shift[2];
115         brush_texture_t         anim;
116         int                             mt;
117
118         if (!bt->name[0])
119                 return 0;
120
121         memset (&tx, 0, sizeof(tx));
122         strcpy (tx.texture, bt->name);
123
124         TextureAxisFromPlane(plane, vecs[0], vecs[1]);
125
126         shift[0] = DotProduct (origin, vecs[0]);
127         shift[1] = DotProduct (origin, vecs[1]);
128
129         if (!bt->scale[0])
130                 bt->scale[0] = 1;
131         if (!bt->scale[1])
132                 bt->scale[1] = 1;
133
134
135 // rotate axis
136         if (bt->rotate == 0)
137                 { sinv = 0 ; cosv = 1; }
138         else if (bt->rotate == 90)
139                 { sinv = 1 ; cosv = 0; }
140         else if (bt->rotate == 180)
141                 { sinv = 0 ; cosv = -1; }
142         else if (bt->rotate == 270)
143                 { sinv = -1 ; cosv = 0; }
144         else
145         {       
146                 ang = bt->rotate / 180 * Q_PI;
147                 sinv = sin(ang);
148                 cosv = cos(ang);
149         }
150
151         if (vecs[0][0])
152                 sv = 0;
153         else if (vecs[0][1])
154                 sv = 1;
155         else
156                 sv = 2;
157                                 
158         if (vecs[1][0])
159                 tv = 0;
160         else if (vecs[1][1])
161                 tv = 1;
162         else
163                 tv = 2;
164                                         
165         for (i=0 ; i<2 ; i++)
166         {
167                 ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
168                 nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
169                 vecs[i][sv] = ns;
170                 vecs[i][tv] = nt;
171         }
172
173         for (i=0 ; i<2 ; i++)
174                 for (j=0 ; j<3 ; j++)
175                         tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
176
177         tx.vecs[0][3] = bt->shift[0] + shift[0];
178         tx.vecs[1][3] = bt->shift[1] + shift[1];
179         tx.flags = bt->flags;
180         tx.value = bt->value;
181
182         //
183         // find the texinfo
184         //
185         tc = texinfo;
186         for (i=0 ; i<numtexinfo ; i++, tc++)
187         {
188                 if (tc->flags != tx.flags)
189                         continue;
190                 if (tc->value != tx.value)
191                         continue;
192                 for (j=0 ; j<2 ; j++)
193                 {
194                         if (strcmp (tc->texture, tx.texture))
195                                 goto skip;
196                         for (k=0 ; k<4 ; k++)
197                         {
198                                 if (tc->vecs[j][k] != tx.vecs[j][k])
199                                         goto skip;
200                         }
201                 }
202                 return i;
203 skip:;
204         }
205         *tc = tx;
206         numtexinfo++;
207
208         // load the next animation
209         mt = FindMiptex (bt->name);
210         if (textureref[mt].animname[0])
211         {
212                 anim = *bt;
213                 strcpy (anim.name, textureref[mt].animname);
214                 tc->nexttexinfo = TexinfoForBrushTexture (plane, &anim, origin);
215         }
216         else
217                 tc->nexttexinfo = -1;
218
219
220         return i;
221 }