2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
5 This file is part of Quake 2 Tools source code.
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.
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.
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 ===========================================================================
25 vec3_t texture_reflectivity[MAX_MAP_TEXINFO];
28 ===================================================================
32 ===================================================================
36 ======================
37 CalcTextureReflectivity
38 ======================
40 void CalcTextureReflectivity (void)
51 sprintf (path, "%spics/colormap.pcx", gamedir);
53 // get the game palette
54 Load256Image (path, NULL, &palette, NULL, NULL);
56 // allways set index 0 even if no textures
57 texture_reflectivity[0][0] = 0.5;
58 texture_reflectivity[0][1] = 0.5;
59 texture_reflectivity[0][2] = 0.5;
61 for (i=0 ; i<numtexinfo ; i++)
63 // see if an earlier texinfo allready got the value
66 if (!strcmp (texinfo[i].texture, texinfo[j].texture))
68 VectorCopy (texture_reflectivity[j], texture_reflectivity[i]);
76 sprintf (path, "%stextures/%s.wal", gamedir, texinfo[i].texture);
77 if (TryLoadFile (path, (void **)&mt) == -1)
79 printf ("Couldn't load %s\n", path);
80 texture_reflectivity[i][0] = 0.5;
81 texture_reflectivity[i][1] = 0.5;
82 texture_reflectivity[i][2] = 0.5;
85 texels = LittleLong(mt->width)*LittleLong(mt->height);
86 color[0] = color[1] = color[2] = 0;
88 for (j=0 ; j<texels ; j++)
90 texel = ((byte *)mt)[LittleLong(mt->offsets[0]) + j];
92 color[k] += palette[texel*3+k];
97 r = color[j]/texels/255.0;
98 texture_reflectivity[i][j] = r;
100 // scale the reflectivity up, because the textures are
102 scale = ColorNormalize (texture_reflectivity[i],
103 texture_reflectivity[i]);
107 VectorScale (texture_reflectivity[i], scale, texture_reflectivity[i]);
110 texture_reflectivity[i][0] = 0.5;
111 texture_reflectivity[i][1] = 0.5;
112 texture_reflectivity[i][2] = 0.5;
118 =======================================================================
122 =======================================================================
130 winding_t *WindingFromFace (dface_t *f)
138 w = AllocWinding (f->numedges);
139 w->numpoints = f->numedges;
141 for (i=0 ; i<f->numedges ; i++)
143 se = dsurfedges[f->firstedge + i];
145 v = dedges[-se].v[1];
150 VectorCopy (dv->point, w->p[i]);
153 RemoveColinearPoints (w);
163 void BaseLightForFace (dface_t *f, vec3_t color)
168 // check for light emited by texture
170 tx = &texinfo[f->texinfo];
171 if (!(tx->flags & SURF_LIGHT) || tx->value == 0)
177 VectorScale (texture_reflectivity[f->texinfo], tx->value, color);
180 qboolean IsSky (dface_t *f)
184 tx = &texinfo[f->texinfo];
185 if (tx->flags & SURF_SKY)
196 void MakePatchForFace (int fn, winding_t *w)
208 area = WindingArea (w);
211 patch = &patches[num_patches];
212 if (num_patches == MAX_PATCHES)
213 Error ("num_patches == MAX_PATCHES");
214 patch->next = face_patches[fn];
215 face_patches[fn] = patch;
220 patch->plane = &backplanes[f->planenum];
222 patch->plane = &dplanes[f->planenum];
223 if (face_offset[fn][0] || face_offset[fn][1] || face_offset[fn][2] )
224 { // origin offset faces must create new planes
225 if (numplanes + fakeplanes >= MAX_MAP_PLANES)
226 Error ("numplanes + fakeplanes >= MAX_MAP_PLANES");
227 pl = &dplanes[numplanes + fakeplanes];
230 *pl = *(patch->plane);
231 pl->dist += DotProduct (face_offset[fn], pl->normal);
235 WindingCenter (w, patch->origin);
236 VectorAdd (patch->origin, patch->plane->normal, patch->origin);
237 leaf = PointInLeaf(patch->origin);
238 patch->cluster = leaf->cluster;
239 if (patch->cluster == -1)
240 qprintf ("patch->cluster == -1\n");
243 if (patch->area <= 1)
245 patch->sky = IsSky (f);
247 VectorCopy (texture_reflectivity[f->texinfo], patch->reflectivity);
249 // non-bmodel patches can emit light
250 if (fn < dmodels[0].numfaces)
252 BaseLightForFace (f, patch->baselight);
254 ColorNormalize (patch->reflectivity, color);
256 for (i=0 ; i<3 ; i++)
257 patch->baselight[i] *= color[i];
259 VectorCopy (patch->baselight, patch->totallight);
265 entity_t *EntityForModel (int modnum)
271 sprintf (name, "*%i", modnum);
272 // search the entities for one using modnum
273 for (i=0 ; i<num_entities ; i++)
275 s = ValueForKey (&entities[i], "model");
276 if (!strcmp (s, name))
288 void MakePatches (void)
298 qprintf ("%i faces\n", numfaces);
300 for (i=0 ; i<nummodels ; i++)
303 ent = EntityForModel (i);
304 // bmodels with origin brushes need to be offset into their
306 GetVectorForKey (ent, "origin", origin);
307 //VectorCopy (vec3_origin, origin);
309 for (j=0 ; j<mod->numfaces ; j++)
311 fn = mod->firstface + j;
312 face_entity[fn] = ent;
313 VectorCopy (origin, face_offset[fn]);
315 w = WindingFromFace (f);
316 for (k=0 ; k<w->numpoints ; k++)
318 VectorAdd (w->p[k], origin, w->p[k]);
320 MakePatchForFace (fn, w);
324 qprintf ("%i sqaure feet\n", (int)(totalarea/64));
328 =======================================================================
332 =======================================================================
335 void FinishSplit (patch_t *patch, patch_t *newp)
339 VectorCopy (patch->baselight, newp->baselight);
340 VectorCopy (patch->totallight, newp->totallight);
341 VectorCopy (patch->reflectivity, newp->reflectivity);
342 newp->plane = patch->plane;
343 newp->sky = patch->sky;
345 patch->area = WindingArea (patch->winding);
346 newp->area = WindingArea (newp->winding);
348 if (patch->area <= 1)
353 WindingCenter (patch->winding, patch->origin);
354 VectorAdd (patch->origin, patch->plane->normal, patch->origin);
355 leaf = PointInLeaf(patch->origin);
356 patch->cluster = leaf->cluster;
357 if (patch->cluster == -1)
358 qprintf ("patch->cluster == -1\n");
360 WindingCenter (newp->winding, newp->origin);
361 VectorAdd (newp->origin, newp->plane->normal, newp->origin);
362 leaf = PointInLeaf(newp->origin);
363 newp->cluster = leaf->cluster;
364 if (newp->cluster == -1)
365 qprintf ("patch->cluster == -1\n");
372 Chops the patch only if its local bounds exceed the max size
375 void SubdividePatch (patch_t *patch)
377 winding_t *w, *o1, *o2;
378 vec3_t mins, maxs, total;
386 mins[0] = mins[1] = mins[2] = 99999;
387 maxs[0] = maxs[1] = maxs[2] = -99999;
388 for (i=0 ; i<w->numpoints ; i++)
390 for (j=0 ; j<3 ; j++)
399 VectorSubtract (maxs, mins, total);
400 for (i=0 ; i<3 ; i++)
401 if (total[i] > (subdiv+1) )
405 // no splitting needed
412 VectorCopy (vec3_origin, split);
414 dist = (mins[i] + maxs[i])*0.5;
415 ClipWindingEpsilon (w, split, dist, ON_EPSILON, &o1, &o2);
418 // create a new patch
420 if (num_patches == MAX_PATCHES)
421 Error ("MAX_PATCHES");
422 newp = &patches[num_patches];
425 newp->next = patch->next;
431 FinishSplit (patch, newp);
433 SubdividePatch (patch);
434 SubdividePatch (newp);
442 Chops the patch by a global grid
445 void DicePatch (patch_t *patch)
447 winding_t *w, *o1, *o2;
455 WindingBounds (w, mins, maxs);
456 for (i=0 ; i<3 ; i++)
457 if (floor((mins[i]+1)/subdiv) < floor((maxs[i]-1)/subdiv))
461 // no splitting needed
468 VectorCopy (vec3_origin, split);
470 dist = subdiv*(1+floor((mins[i]+1)/subdiv));
471 ClipWindingEpsilon (w, split, dist, ON_EPSILON, &o1, &o2);
474 // create a new patch
476 if (num_patches == MAX_PATCHES)
477 Error ("MAX_PATCHES");
478 newp = &patches[num_patches];
481 newp->next = patch->next;
487 FinishSplit (patch, newp);
499 void SubdividePatches (void)
506 num = num_patches; // because the list will grow
507 for (i=0 ; i<num ; i++)
509 // SubdividePatch (&patches[i]);
510 DicePatch (&patches[i]);
512 qprintf ("%i patches after subdivision\n", num_patches);
515 //=====================================================================