home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / bsp / qrad3 / patches.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-18  |  9.8 KB  |  495 lines

  1.  
  2. #include "qrad.h"
  3.  
  4. vec3_t    texture_reflectivity[MAX_MAP_TEXINFO];
  5.  
  6. /*
  7. ===================================================================
  8.  
  9.   TEXTURE LIGHT VALUES
  10.  
  11. ===================================================================
  12. */
  13.  
  14. /*
  15. ======================
  16. CalcTextureReflectivity
  17. ======================
  18. */
  19. void CalcTextureReflectivity (void)
  20. {
  21.     int                i;
  22.     int                j, k, texels;
  23.     int                color[3];
  24.     int                texel;
  25.     byte            *palette;
  26.     char            path[1024];
  27.     float            r, scale;
  28.     miptex_t        *mt;
  29.  
  30.     sprintf (path, "%spics/colormap.pcx", gamedir);
  31.  
  32.     // get the game palette
  33.     Load256Image (path, NULL, &palette, NULL, NULL);
  34.  
  35.     // allways set index 0 even if no textures
  36.     texture_reflectivity[0][0] = 0.5;
  37.     texture_reflectivity[0][1] = 0.5;
  38.     texture_reflectivity[0][2] = 0.5;
  39.  
  40.     for (i=0 ; i<numtexinfo ; i++)
  41.     {
  42.         // see if an earlier texinfo allready got the value
  43.         for (j=0 ; j<i ; j++)
  44.         {
  45.             if (!strcmp (texinfo[i].texture, texinfo[j].texture))
  46.             {
  47.                 VectorCopy (texture_reflectivity[j], texture_reflectivity[i]);
  48.                 break;
  49.             }
  50.         }
  51.         if (j != i)
  52.             continue;
  53.  
  54.         // load the wal file
  55.         sprintf (path, "%stextures/%s.wal", gamedir, texinfo[i].texture);
  56.         if (TryLoadFile (path, (void **)&mt) == -1)
  57.         {
  58.             printf ("Couldn't load %s\n", path);
  59.             texture_reflectivity[i][0] = 0.5;
  60.             texture_reflectivity[i][1] = 0.5;
  61.             texture_reflectivity[i][2] = 0.5;
  62.             continue;
  63.         }
  64.         texels = LittleLong(mt->width)*LittleLong(mt->height);
  65.         color[0] = color[1] = color[2] = 0;
  66.  
  67.         for (j=0 ; j<texels ; j++)
  68.         {
  69.             texel = ((byte *)mt)[LittleLong(mt->offsets[0]) + j];
  70.             for (k=0 ; k<3 ; k++)
  71.                 color[k] += palette[texel*3+k];
  72.         }
  73.  
  74.         for (j=0 ; j<3 ; j++)
  75.         {
  76.             r = color[j]/texels/255.0;
  77.             texture_reflectivity[i][j] = r;
  78.         }
  79.         // scale the reflectivity up, because the textures are
  80.         // so dim
  81.         scale = ColorNormalize (texture_reflectivity[i],
  82.             texture_reflectivity[i]);
  83.         if (scale < 0.5)
  84.         {
  85.             scale *= 2;
  86.             VectorScale (texture_reflectivity[i], scale, texture_reflectivity[i]);
  87.         }
  88. #if 0
  89. texture_reflectivity[i][0] = 0.5;
  90. texture_reflectivity[i][1] = 0.5;
  91. texture_reflectivity[i][2] = 0.5;
  92. #endif
  93.     }
  94. }
  95.  
  96. /*
  97. =======================================================================
  98.  
  99. MAKE FACES
  100.  
  101. =======================================================================
  102. */
  103.  
  104. /*
  105. =============
  106. WindingFromFace
  107. =============
  108. */
  109. winding_t    *WindingFromFace (dface_t *f)
  110. {
  111.     int            i;
  112.     int            se;
  113.     dvertex_t    *dv;
  114.     int            v;
  115.     winding_t    *w;
  116.  
  117.     w = AllocWinding (f->numedges);
  118.     w->numpoints = f->numedges;
  119.  
  120.     for (i=0 ; i<f->numedges ; i++)
  121.     {
  122.         se = dsurfedges[f->firstedge + i];
  123.         if (se < 0)
  124.             v = dedges[-se].v[1];
  125.         else
  126.             v = dedges[se].v[0];
  127.  
  128.         dv = &dvertexes[v];
  129.         VectorCopy (dv->point, w->p[i]);
  130.     }
  131.  
  132.     RemoveColinearPoints (w);
  133.  
  134.     return w;
  135. }
  136.  
  137. /*
  138. =============
  139. BaseLightForFace
  140. =============
  141. */
  142. void BaseLightForFace (dface_t *f, vec3_t color)
  143. {
  144.     texinfo_t    *tx;
  145.  
  146.     //
  147.     // check for light emited by texture
  148.     //
  149.     tx = &texinfo[f->texinfo];
  150.     if (!(tx->flags & SURF_LIGHT) || tx->value == 0)
  151.     {
  152.         VectorClear (color);
  153.         return;
  154.     }
  155.  
  156.     VectorScale (texture_reflectivity[f->texinfo], tx->value, color);
  157. }
  158.  
  159. qboolean IsSky (dface_t *f)
  160. {
  161.     texinfo_t    *tx;
  162.  
  163.     tx = &texinfo[f->texinfo];
  164.     if (tx->flags & SURF_SKY)
  165.         return true;
  166.     return false;
  167. }
  168.  
  169. /*
  170. =============
  171. MakePatchForFace
  172. =============
  173. */
  174. float    totalarea;
  175. void MakePatchForFace (int fn, winding_t *w)
  176. {
  177.     dface_t *f;
  178.     float    area;
  179.     patch_t        *patch;
  180.     dplane_t    *pl;
  181.     int            i;
  182.     vec3_t        color;
  183.     dleaf_t        *leaf;
  184.  
  185.     f = &dfaces[fn];
  186.  
  187.     area = WindingArea (w);
  188.     totalarea += area;
  189.  
  190.     patch = &patches[num_patches];
  191.     if (num_patches == MAX_PATCHES)
  192.         Error ("num_patches == MAX_PATCHES");
  193.     patch->next = face_patches[fn];
  194.     face_patches[fn] = patch;
  195.  
  196.     patch->winding = w;
  197.  
  198.     if (f->side)
  199.         patch->plane = &backplanes[f->planenum];
  200.     else
  201.         patch->plane = &dplanes[f->planenum];
  202.     if (face_offset[fn][0] || face_offset[fn][1] || face_offset[fn][2] )
  203.     {    // origin offset faces must create new planes
  204.         if (numplanes + fakeplanes >= MAX_MAP_PLANES)
  205.             Error ("numplanes + fakeplanes >= MAX_MAP_PLANES");
  206.         pl = &dplanes[numplanes + fakeplanes];
  207.         fakeplanes++;
  208.  
  209.         *pl = *(patch->plane);
  210.         pl->dist += DotProduct (face_offset[fn], pl->normal);
  211.         patch->plane = pl;
  212.     }
  213.  
  214.     WindingCenter (w, patch->origin);
  215.     VectorAdd (patch->origin, patch->plane->normal, patch->origin);
  216.     leaf = PointInLeaf(patch->origin);
  217.     patch->cluster = leaf->cluster;
  218.     if (patch->cluster == -1)
  219.         qprintf ("patch->cluster == -1\n");
  220.  
  221.     patch->area = area;
  222.     if (patch->area <= 1)
  223.         patch->area = 1;
  224.     patch->sky = IsSky (f);
  225.  
  226.     VectorCopy (texture_reflectivity[f->texinfo], patch->reflectivity);
  227.  
  228.     // non-bmodel patches can emit light
  229.     if (fn < dmodels[0].numfaces)
  230.     {
  231.         BaseLightForFace (f, patch->baselight);
  232.  
  233.         ColorNormalize (patch->reflectivity, color);
  234.  
  235.         for (i=0 ; i<3 ; i++)
  236.             patch->baselight[i] *= color[i];
  237.  
  238.         VectorCopy (patch->baselight, patch->totallight);
  239.     }
  240.     num_patches++;
  241. }
  242.  
  243.  
  244. entity_t *EntityForModel (int modnum)
  245. {
  246.     int        i;
  247.     char    *s;
  248.     char    name[16];
  249.  
  250.     sprintf (name, "*%i", modnum);
  251.     // search the entities for one using modnum
  252.     for (i=0 ; i<num_entities ; i++)
  253.     {
  254.         s = ValueForKey (&entities[i], "model");
  255.         if (!strcmp (s, name))
  256.             return &entities[i];
  257.     }
  258.  
  259.     return &entities[0];
  260. }
  261.  
  262. /*
  263. =============
  264. MakePatches
  265. =============
  266. */
  267. void MakePatches (void)
  268. {
  269.     int        i, j, k;
  270.     dface_t    *f;
  271.     int        fn;
  272.     winding_t    *w;
  273.     dmodel_t    *mod;
  274.     vec3_t        origin;
  275.     entity_t    *ent;
  276.  
  277.     qprintf ("%i faces\n", numfaces);
  278.  
  279.     for (i=0 ; i<nummodels ; i++)
  280.     {
  281.         mod = &dmodels[i];
  282.         ent = EntityForModel (i);
  283.         // bmodels with origin brushes need to be offset into their
  284.         // in-use position
  285.         GetVectorForKey (ent, "origin", origin);
  286. //VectorCopy (vec3_origin, origin);
  287.  
  288.         for (j=0 ; j<mod->numfaces ; j++)
  289.         {
  290.             fn = mod->firstface + j;
  291.             face_entity[fn] = ent;
  292.             VectorCopy (origin, face_offset[fn]);
  293.             f = &dfaces[fn];
  294.             w = WindingFromFace (f);
  295.             for (k=0 ; k<w->numpoints ; k++)
  296.             {
  297.                 VectorAdd (w->p[k], origin, w->p[k]);
  298.             }
  299.             MakePatchForFace (fn, w);
  300.         }
  301.     }
  302.  
  303.     qprintf ("%i sqaure feet\n", (int)(totalarea/64));
  304. }
  305.  
  306. /*
  307. =======================================================================
  308.  
  309. SUBDIVIDE
  310.  
  311. =======================================================================
  312. */
  313.  
  314. void FinishSplit (patch_t *patch, patch_t *newp)
  315. {
  316.     dleaf_t        *leaf;
  317.  
  318.     VectorCopy (patch->baselight, newp->baselight);
  319.     VectorCopy (patch->totallight, newp->totallight);
  320.     VectorCopy (patch->reflectivity, newp->reflectivity);
  321.     newp->plane = patch->plane;
  322.     newp->sky = patch->sky;
  323.  
  324.     patch->area = WindingArea (patch->winding);
  325.     newp->area = WindingArea (newp->winding);
  326.  
  327.     if (patch->area <= 1)
  328.         patch->area = 1;
  329.     if (newp->area <= 1)
  330.         newp->area = 1;
  331.  
  332.     WindingCenter (patch->winding, patch->origin);
  333.     VectorAdd (patch->origin, patch->plane->normal, patch->origin);
  334.     leaf = PointInLeaf(patch->origin);
  335.     patch->cluster = leaf->cluster;
  336.     if (patch->cluster == -1)
  337.         qprintf ("patch->cluster == -1\n");
  338.  
  339.     WindingCenter (newp->winding, newp->origin);
  340.     VectorAdd (newp->origin, newp->plane->normal, newp->origin);
  341.     leaf = PointInLeaf(newp->origin);
  342.     newp->cluster = leaf->cluster;
  343.     if (newp->cluster == -1)
  344.         qprintf ("patch->cluster == -1\n");
  345. }
  346.  
  347. /*
  348. =============
  349. SubdividePatch
  350.  
  351. Chops the patch only if its local bounds exceed the max size
  352. =============
  353. */
  354. void    SubdividePatch (patch_t *patch)
  355. {
  356.     winding_t *w, *o1, *o2;
  357.     vec3_t    mins, maxs, total;
  358.     vec3_t    split;
  359.     vec_t    dist;
  360.     int        i, j;
  361.     vec_t    v;
  362.     patch_t    *newp;
  363.  
  364.     w = patch->winding;
  365.     mins[0] = mins[1] = mins[2] = 99999;
  366.     maxs[0] = maxs[1] = maxs[2] = -99999;
  367.     for (i=0 ; i<w->numpoints ; i++)
  368.     {
  369.         for (j=0 ; j<3 ; j++)
  370.         {
  371.             v = w->p[i][j];
  372.             if (v < mins[j])
  373.                 mins[j] = v;
  374.             if (v > maxs[j])
  375.                 maxs[j] = v;
  376.         }
  377.     }
  378.     VectorSubtract (maxs, mins, total);
  379.     for (i=0 ; i<3 ; i++)
  380.         if (total[i] > (subdiv+1) )
  381.             break;
  382.     if (i == 3)
  383.     {
  384.         // no splitting needed
  385.         return;        
  386.     }
  387.  
  388.     //
  389.     // split the winding
  390.     //
  391.     VectorCopy (vec3_origin, split);
  392.     split[i] = 1;
  393.     dist = (mins[i] + maxs[i])*0.5;
  394.     ClipWindingEpsilon (w, split, dist, ON_EPSILON, &o1, &o2);
  395.  
  396.     //
  397.     // create a new patch
  398.     //
  399.     if (num_patches == MAX_PATCHES)
  400.         Error ("MAX_PATCHES");
  401.     newp = &patches[num_patches];
  402.     num_patches++;
  403.  
  404.     newp->next = patch->next;
  405.     patch->next = newp;
  406.  
  407.     patch->winding = o1;
  408.     newp->winding = o2;
  409.  
  410.     FinishSplit (patch, newp);
  411.  
  412.     SubdividePatch (patch);
  413.     SubdividePatch (newp);
  414. }
  415.  
  416.  
  417. /*
  418. =============
  419. DicePatch
  420.  
  421. Chops the patch by a global grid
  422. =============
  423. */
  424. void    DicePatch (patch_t *patch)
  425. {
  426.     winding_t *w, *o1, *o2;
  427.     vec3_t    mins, maxs;
  428.     vec3_t    split;
  429.     vec_t    dist;
  430.     int        i;
  431.     patch_t    *newp;
  432.  
  433.     w = patch->winding;
  434.     WindingBounds (w, mins, maxs);
  435.     for (i=0 ; i<3 ; i++)
  436.         if (floor((mins[i]+1)/subdiv) < floor((maxs[i]-1)/subdiv))
  437.             break;
  438.     if (i == 3)
  439.     {
  440.         // no splitting needed
  441.         return;        
  442.     }
  443.  
  444.     //
  445.     // split the winding
  446.     //
  447.     VectorCopy (vec3_origin, split);
  448.     split[i] = 1;
  449.     dist = subdiv*(1+floor((mins[i]+1)/subdiv));
  450.     ClipWindingEpsilon (w, split, dist, ON_EPSILON, &o1, &o2);
  451.  
  452.     //
  453.     // create a new patch
  454.     //
  455.     if (num_patches == MAX_PATCHES)
  456.         Error ("MAX_PATCHES");
  457.     newp = &patches[num_patches];
  458.     num_patches++;
  459.  
  460.     newp->next = patch->next;
  461.     patch->next = newp;
  462.  
  463.     patch->winding = o1;
  464.     newp->winding = o2;
  465.  
  466.     FinishSplit (patch, newp);
  467.  
  468.     DicePatch (patch);
  469.     DicePatch (newp);
  470. }
  471.  
  472.  
  473. /*
  474. =============
  475. SubdividePatches
  476. =============
  477. */
  478. void SubdividePatches (void)
  479. {
  480.     int        i, num;
  481.  
  482.     if (subdiv < 1)
  483.         return;
  484.  
  485.     num = num_patches;    // because the list will grow
  486.     for (i=0 ; i<num ; i++)
  487.     {
  488. //        SubdividePatch (&patches[i]);
  489.         DicePatch (&patches[i]);
  490.     }
  491.     qprintf ("%i patches after subdivision\n", num_patches);
  492. }
  493.  
  494. //=====================================================================
  495.