textures.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 1997-2001 Id Software, Inc.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 
00026 #include "bsp.h"
00027 
00028 static int nummiptex = 0;
00029 textureref_t textureref[MAX_MAP_TEXTURES];
00030 
00037 int FindMiptex (const char *name)
00038 {
00039     int i;
00040 
00041     /* search through textures that have already been loaded. */
00042     for (i = 0; i < nummiptex; i++)
00043         if (!strcmp(name, textureref[i].name)) {
00044             return i;
00045         }
00046     if (nummiptex == MAX_MAP_TEXTURES)
00047         Sys_Error("MAX_MAP_TEXTURES");
00048     Q_strncpyz(textureref[i].name, name, sizeof(textureref[i].name));
00049 
00050     return i;
00051 }
00052 
00053 
00054 static const vec3_t baseaxis[18] =
00055 {
00056 {0,0,1}, {1,0,0}, {0,-1,0},         /* floor */
00057 {0,0,-1}, {1,0,0}, {0,-1,0},        /* ceiling */
00058 {1,0,0}, {0,1,0}, {0,0,-1},         /* west wall */
00059 {-1,0,0}, {0,1,0}, {0,0,-1},        /* east wall */
00060 {0,1,0}, {1,0,0}, {0,0,-1},         /* south wall */
00061 {0,-1,0}, {1,0,0}, {0,0,-1}         /* north wall */
00062 };
00063 
00064 static void TextureAxisFromPlane (plane_t *pln, vec3_t xv, vec3_t yv, qboolean isTerrain)
00065 {
00066     int bestaxis, numaxis, i;
00067     vec_t best;
00068 
00069     /* Knightmare- terrain support, use floor/ceiling axis only */
00070     numaxis = (isTerrain) ? 2 : 6;
00071 
00072     best = 0;
00073     bestaxis = 0;
00074 
00075     for (i = 0; i < numaxis; i++) {
00076         const vec_t dot = DotProduct(pln->normal, baseaxis[i * 3]);
00077         if (dot > best) {
00078             best = dot;
00079             bestaxis = i;
00080         }
00081     }
00082 
00083     VectorCopy(baseaxis[bestaxis * 3 + 1], xv);
00084     VectorCopy(baseaxis[bestaxis * 3 + 2], yv);
00085 }
00086 
00087 
00091 int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, const vec3_t origin, qboolean isTerrain)
00092 {
00093     vec3_t vecs[2];
00094     int sv, tv;
00095     vec_t ang, sinv, cosv;
00096     dBspTexinfo_t tx, *tc;
00097     int i, j, k;
00098     float shift[2];
00099     vec3_t scaledOrigin;
00100 
00101     if (!bt->name[0])
00102         return 0;
00103 
00104     memset(&tx, 0, sizeof(tx));
00105     Q_strncpyz(tx.texture, bt->name, sizeof(tx.texture));
00106 
00107     TextureAxisFromPlane(plane, vecs[0], vecs[1], isTerrain);
00108 
00109     /* dot product of a vertex location with the [4] part will produce a
00110      * texcoord (s or t depending on the first index) */
00111     VectorScale(origin, 1.0 / bt->scale[0], scaledOrigin);
00112     shift[0] = DotProduct(scaledOrigin, vecs[0]);
00113     VectorScale(origin, 1.0 / bt->scale[1], scaledOrigin);
00114     shift[1] = DotProduct(scaledOrigin, vecs[1]);
00115 
00116     if (!bt->scale[0])
00117         bt->scale[0] = 1;
00118     if (!bt->scale[1])
00119         bt->scale[1] = 1;
00120 
00121     /* rotate axis */
00122     if (bt->rotate == 0) {
00123         sinv = 0;
00124         cosv = 1;
00125     } else if (bt->rotate == 90) {
00126         sinv = 1;
00127         cosv = 0;
00128     } else if (bt->rotate == 180) {
00129         sinv = 0;
00130         cosv = -1;
00131     } else if (bt->rotate == 270) {
00132         sinv = -1;
00133         cosv = 0;
00134     } else {
00135         ang = bt->rotate * torad;
00136         sinv = sin(ang);
00137         cosv = cos(ang);
00138     }
00139 
00140     shift[0] = cosv * shift[0] - sinv * shift[1];
00141     shift[1] = sinv * shift[0] + cosv * shift[1];
00142 
00143     if (vecs[0][0])
00144         sv = 0;
00145     else if (vecs[0][1])
00146         sv = 1;
00147     else
00148         sv = 2;
00149 
00150     if (vecs[1][0])
00151         tv = 0;
00152     else if (vecs[1][1])
00153         tv = 1;
00154     else
00155         tv = 2;
00156 
00157     for (i = 0; i < 2; i++) {
00158         const vec_t ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
00159         const vec_t nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
00160         vecs[i][sv] = ns;
00161         vecs[i][tv] = nt;
00162     }
00163 
00164     for (i = 0; i < 2; i++)
00165         for (j = 0; j < 3; j++)
00166             tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
00167 
00168     /* texture offsets */
00169     tx.vecs[0][3] = bt->shift[0] + shift[0];
00170     tx.vecs[1][3] = bt->shift[1] + shift[1];
00171 
00172     tx.surfaceFlags = bt->surfaceFlags;
00173     tx.value = bt->value;
00174 
00175     /* find the texinfo */
00176     tc = curTile->texinfo;
00177     for (i = 0; i < curTile->numtexinfo; i++, tc++) {
00178         if (tc->surfaceFlags != tx.surfaceFlags)
00179             continue;
00180         if (tc->value != tx.value)
00181             continue;
00182         if (strcmp(tc->texture, tx.texture))
00183             continue;
00184         for (j = 0; j < 2; j++) {
00185             for (k = 0; k < 4; k++) {
00186                 if (tc->vecs[j][k] != tx.vecs[j][k])
00187                     goto skip;
00188             }
00189         }
00190         return i;
00191 skip:;
00192     }
00193     if (curTile->numtexinfo >= MAX_MAP_TEXINFO)
00194         Sys_Error("MAX_MAP_TEXINFO overflow");
00195     *tc = tx;
00196     curTile->numtexinfo++;
00197 
00198     return i;
00199 }

Generated by  doxygen 1.6.2