1 // Copyright (C) 2000  Sean Cavanaugh
2 // This file is licensed under the terms of the Lesser GNU Public License
3 // (see LPGL.txt, or http://www.gnu.org/copyleft/lesser.txt)
4 
5 #pragma warning(disable: 4018) //amckern - 64bit - '<' Singed/Unsigned Mismatch
6 
7 #include "vis.h"
8 
9 
set(UINT32 zone,const BoundingBox & bounds)10 void Zones::set(UINT32 zone, const BoundingBox& bounds)
11 {
12     if (zone < m_ZoneCount)
13     {
14         m_ZoneBounds[zone] = bounds;
15     }
16 }
17 
getZoneFromBounds(const BoundingBox & bounds)18 UINT32 Zones::getZoneFromBounds(const BoundingBox& bounds)
19 {
20     UINT32 x;
21     for (x=0; x<m_ZoneCount; x++)
22     {
23         if (m_ZoneBounds[x].testSuperset(bounds))
24         {
25             return x;
26         }
27     }
28     return 0;
29 }
30 
getZoneFromWinding(const Winding & winding)31 UINT32 Zones::getZoneFromWinding(const Winding& winding)
32 {
33     UINT32          x;
34     BoundingBox     bounds;
35 
36     for (x=0; x<winding.m_NumPoints; x++)
37     {
38         bounds.add(winding.m_Points[x]);
39     }
40 
41     return getZoneFromBounds(bounds);
42 }
43 
44 // BORROWED FROM HLRAD
45 // TODO: Consolite into common sometime
WindingFromFace(const dface_t * f)46 static Winding*      WindingFromFace(const dface_t* f)
47 {
48     int             i;
49     int             se;
50     dvertex_t*      dv;
51     int             v;
52     Winding*        w = new Winding(f->numedges);
53 
54     for (i = 0; i < f->numedges; i++)
55     {
56         se = g_dsurfedges[f->firstedge + i];
57         if (se < 0)
58         {
59             v = g_dedges[-se].v[1];
60         }
61         else
62         {
63             v = g_dedges[se].v[0];
64         }
65 
66         dv = &g_dvertexes[v];
67         VectorCopy(dv->point, w->m_Points[i]);
68     }
69 
70     return w;
71 }
72 
MakeZones(void)73 Zones* MakeZones(void)
74 {
75     UINT32 x;
76     UINT32 func_vis_count = 0;
77 
78     ParseEntities();
79 
80     // Note: we arent looping through entities because we only care if it has a winding/bounding box
81 
82     // First count the number of func_vis's
83     for (x=0; x<g_nummodels; x++)
84     {
85         entity_t*       ent = EntityForModel(x);
86 
87         if (!strcasecmp(ValueForKey(ent, "classname"), "func_vis"))
88         {
89             UINT32 value = atoi(ValueForKey(ent, "node"));
90             if (value)
91             {
92                 func_vis_count++;
93             }
94             else
95             {
96                 Error("func_vis with no \"node\" id\n");
97             }
98         }
99     }
100 
101     if (!func_vis_count)
102     {
103         return NULL;
104     }
105 
106     Zones* zones = new Zones(func_vis_count);
107 
108     for (x=0; x<g_nummodels; x++)
109     {
110         dmodel_t*       mod = g_dmodels + x;
111         entity_t*       ent = EntityForModel(x);
112 
113         if (!strcasecmp(ValueForKey(ent, "classname"), "func_vis"))
114         {
115             UINT32 func_vis_id = atoi(ValueForKey(ent, "node"));
116 
117             {
118                 epair_t* keyvalue;
119 
120                 for (keyvalue = ent->epairs; keyvalue; keyvalue = keyvalue->next)
121                 {
122                     UINT32 other_id = atoi(keyvalue->key);
123                     if (other_id)
124                     {
125                         zones->flag(func_vis_id, other_id);
126                     }
127                 }
128             }
129 
130             {
131                 UINT32          j;
132                 BoundingBox     bounds;
133                 dface_t*        f = g_dfaces + mod->firstface;
134 
135                 for (j = 0; j < mod->numfaces; j++, f++)
136                 {
137                     Winding*        w = WindingFromFace(f);
138                     UINT32          k;
139 
140                     for (k = 0; k < w->m_NumPoints; k++)
141                     {
142                         bounds.add(w->m_Points[k]);
143                     }
144                     delete w;
145                 }
146 
147                 zones->set(func_vis_id, bounds);
148 
149                 Log("Adding zone %u : mins(%4.3f %4.3f %4.3f) maxs(%4.3f %4.3f %4.3f)\n", func_vis_id,
150                     bounds.m_Mins[0],bounds.m_Mins[1],bounds.m_Mins[2],
151                     bounds.m_Maxs[0],bounds.m_Maxs[1],bounds.m_Maxs[2]);
152             }
153         }
154     }
155 
156     return zones;
157 }
158