]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/q2map/textures.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / q2map / textures.c
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 #include "qbsp.h"\r
23 \r
24 int             nummiptex;\r
25 textureref_t    textureref[MAX_MAP_TEXTURES];\r
26 \r
27 //==========================================================================\r
28 \r
29 \r
30 int     FindMiptex (char *name)\r
31 {\r
32         int             i;\r
33         char    path[1024];\r
34         miptex_t        *mt;\r
35         miptex_m8_t     *mt_m8;\r
36         miptex_m32_t    *mt_m32;\r
37 \r
38         for (i=0 ; i<nummiptex ; i++)\r
39                 if (!strcmp (name, textureref[i].name))\r
40                 {\r
41                         return i;\r
42                 }\r
43         if (nummiptex == MAX_MAP_TEXTURES)\r
44                 Error ("MAX_MAP_TEXTURES");\r
45         strcpy (textureref[i].name, name);\r
46 \r
47         // load the miptex to get the flags and values\r
48         if ( !strcmp( game, "heretic2" ) )\r
49         {\r
50                 sprintf (path, "%stextures/%s.m32", gamedir, name);\r
51                 if (TryLoadFile (path, (void **)&mt_m32) != -1)\r
52                 {\r
53                         textureref[i].value = LittleLong (mt_m32->value);\r
54                         textureref[i].flags = LittleLong (mt_m32->flags);\r
55                         textureref[i].contents = LittleLong (mt_m32->contents);\r
56                         strcpy (textureref[i].animname, mt_m32->animname);\r
57                         free (mt_m32);\r
58                 }\r
59                 else\r
60                         sprintf (path, "%stextures/%s.m8", gamedir, name);\r
61                 \r
62                 if (TryLoadFile (path, (void **)&mt_m8) != -1)\r
63                 {\r
64                         textureref[i].value = LittleLong (mt_m8->value);\r
65                         textureref[i].flags = LittleLong (mt_m8->flags);\r
66                         textureref[i].contents = LittleLong (mt_m8->contents);\r
67                         strcpy (textureref[i].animname, mt_m8->animname);\r
68                         free (mt_m8);\r
69                 }\r
70         }\r
71         else\r
72         {\r
73         sprintf (path, "%stextures/%s.wal", gamedir, name);\r
74                 if (TryLoadFile (path, (void **)&mt) != -1)\r
75                 {\r
76                         textureref[i].value = LittleLong (mt->value);\r
77                         textureref[i].flags = LittleLong (mt->flags);\r
78                         textureref[i].contents = LittleLong (mt->contents);\r
79                         strcpy (textureref[i].animname, mt->animname);\r
80                         free (mt);\r
81                 }\r
82         }\r
83         \r
84         nummiptex++;\r
85 \r
86         if (textureref[i].animname[0])\r
87                 FindMiptex (textureref[i].animname);\r
88 \r
89         return i;\r
90 }\r
91 \r
92 \r
93 /*\r
94 ==================\r
95 textureAxisFromPlane\r
96 ==================\r
97 */\r
98 vec3_t  baseaxis[18] =\r
99 {\r
100 {0,0,1}, {1,0,0}, {0,-1,0},                     // floor\r
101 {0,0,-1}, {1,0,0}, {0,-1,0},            // ceiling\r
102 {1,0,0}, {0,1,0}, {0,0,-1},                     // west wall\r
103 {-1,0,0}, {0,1,0}, {0,0,-1},            // east wall\r
104 {0,1,0}, {1,0,0}, {0,0,-1},                     // south wall\r
105 {0,-1,0}, {1,0,0}, {0,0,-1}                     // north wall\r
106 };\r
107 \r
108 void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)\r
109 {\r
110         int             bestaxis;\r
111         vec_t   dot,best;\r
112         int             i;\r
113         \r
114         best = 0;\r
115         bestaxis = 0;\r
116         \r
117         for (i=0 ; i<6 ; i++)\r
118         {\r
119                 dot = DotProduct (pln->normal, baseaxis[i*3]);\r
120                 if (dot > best)\r
121                 {\r
122                         best = dot;\r
123                         bestaxis = i;\r
124                 }\r
125         }\r
126         \r
127         VectorCopy (baseaxis[bestaxis*3+1], xv);\r
128         VectorCopy (baseaxis[bestaxis*3+2], yv);\r
129 }\r
130 \r
131 \r
132 \r
133 \r
134 int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin)\r
135 {\r
136         vec3_t  vecs[2];\r
137         int             sv, tv;\r
138         vec_t   ang, sinv, cosv;\r
139         vec_t   ns, nt;\r
140         texinfo_t       tx, *tc;\r
141         int             i, j, k;\r
142         float   shift[2];\r
143         brush_texture_t         anim;\r
144         int                             mt;\r
145 \r
146         if (!bt->name[0])\r
147                 return 0;\r
148 \r
149         memset (&tx, 0, sizeof(tx));\r
150         strcpy (tx.texture, bt->name);\r
151 \r
152         TextureAxisFromPlane(plane, vecs[0], vecs[1]);\r
153 \r
154         shift[0] = DotProduct (origin, vecs[0]);\r
155         shift[1] = DotProduct (origin, vecs[1]);\r
156 \r
157         if (!bt->scale[0])\r
158                 bt->scale[0] = 1;\r
159         if (!bt->scale[1])\r
160                 bt->scale[1] = 1;\r
161 \r
162 \r
163 // rotate axis\r
164         if (bt->rotate == 0)\r
165                 { sinv = 0 ; cosv = 1; }\r
166         else if (bt->rotate == 90)\r
167                 { sinv = 1 ; cosv = 0; }\r
168         else if (bt->rotate == 180)\r
169                 { sinv = 0 ; cosv = -1; }\r
170         else if (bt->rotate == 270)\r
171                 { sinv = -1 ; cosv = 0; }\r
172         else\r
173         {       \r
174                 ang = bt->rotate / 180 * Q_PI;\r
175                 sinv = sin(ang);\r
176                 cosv = cos(ang);\r
177         }\r
178 \r
179         if (vecs[0][0])\r
180                 sv = 0;\r
181         else if (vecs[0][1])\r
182                 sv = 1;\r
183         else\r
184                 sv = 2;\r
185                                 \r
186         if (vecs[1][0])\r
187                 tv = 0;\r
188         else if (vecs[1][1])\r
189                 tv = 1;\r
190         else\r
191                 tv = 2;\r
192                                         \r
193         for (i=0 ; i<2 ; i++)\r
194         {\r
195                 ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];\r
196                 nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];\r
197                 vecs[i][sv] = ns;\r
198                 vecs[i][tv] = nt;\r
199         }\r
200 \r
201         for (i=0 ; i<2 ; i++)\r
202                 for (j=0 ; j<3 ; j++)\r
203                         tx.vecs[i][j] = vecs[i][j] / bt->scale[i];\r
204 \r
205         tx.vecs[0][3] = bt->shift[0] + shift[0];\r
206         tx.vecs[1][3] = bt->shift[1] + shift[1];\r
207         tx.flags = bt->flags;\r
208         tx.value = bt->value;\r
209 \r
210         //\r
211         // find the texinfo\r
212         //\r
213         tc = texinfo;\r
214         for (i=0 ; i<numtexinfo ; i++, tc++)\r
215         {\r
216                 if (tc->flags != tx.flags)\r
217                         continue;\r
218                 if (tc->value != tx.value)\r
219                         continue;\r
220                 for (j=0 ; j<2 ; j++)\r
221                 {\r
222                         if (strcmp (tc->texture, tx.texture))\r
223                                 goto skip;\r
224                         for (k=0 ; k<4 ; k++)\r
225                         {\r
226                                 if (tc->vecs[j][k] != tx.vecs[j][k])\r
227                                         goto skip;\r
228                         }\r
229                 }\r
230                 return i;\r
231 skip:;\r
232         }\r
233         *tc = tx;\r
234         numtexinfo++;\r
235 \r
236         // load the next animation\r
237         mt = FindMiptex (bt->name);\r
238         if (textureref[mt].animname[0])\r
239         {\r
240                 anim = *bt;\r
241                 strcpy (anim.name, textureref[mt].animname);\r
242                 tc->nexttexinfo = TexinfoForBrushTexture (plane, &anim, origin);\r
243         }\r
244         else\r
245                 tc->nexttexinfo = -1;\r
246 \r
247 \r
248         return i;\r
249 }\r