convert line ends
[canaan.git] / prj / cam / src / physics / phterr.cpp
blob518bacf65b56a3b43b65ef1f2d2b2ae00cd9b695
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 ///////////////////////////////////////////////////////////////////////////////
7 // $Header: r:/t2repos/thief2/src/physics/phterr.cpp,v 1.12 2000/02/19 12:32:23 toml Exp $
8 //
9 //
12 #include <lg.h>
13 #include <matrix.h>
14 #include <math.h>
15 #include <wrfunc.h>
17 #include <phcontct.h>
18 #include <phterr.h>
20 class cPhysSubModelInst;
22 ///////////////////////////////////////////////////////////////////////////////
24 // CLASS: cPhysTerrPolyList
27 cPhysTerrPolyList::~cPhysTerrPolyList(void)
29 cPhysTerrPoly *pPoly = GetFirst();
30 while (pPoly != NULL)
32 delete pPoly;
33 pPoly = GetFirst();
37 ///////////////////////////////////////
39 BOOL cPhysTerrPolyList::GetNormal(mxs_vector & normal, const mxs_vector &sphere_loc, mxs_real sphere_radius) const
41 cPhysTerrPoly *pPoly = GetFirst();
43 // count the number of polygons
44 int poly_count = 0;
45 while (pPoly != NULL)
47 poly_count++;
48 pPoly = pPoly->GetNext();
51 switch (poly_count)
53 case 0:
55 Warning(("Zero-length poly list?\n"));
56 return FALSE;
59 case 1:
61 pPoly = GetFirst();
62 mx_copy_vec(&normal, &pPoly->GetNormal());
63 break;
66 case 2:
68 mxs_vector *start, *end;
69 int cell_id, poly_id;
70 int offset, offset_max;
71 int i, j;
73 mxs_real best_edge_dist = -1.0;
75 pPoly = GetFirst();
76 while (pPoly != NULL)
78 cell_id = pPoly->GetCellID();
79 poly_id = pPoly->GetPolyID();
81 // Find starting offset of poly
82 offset = 0;
83 for (i=0; i<poly_id; i++)
84 offset += WR_CELL(cell_id)->poly_list[i].num_vertices;
86 offset_max = offset + WR_CELL(cell_id)->poly_list[poly_id].num_vertices;
88 // Find an edge that contains the collision point
89 for (i=offset; i<offset_max; i++)
91 j = ((i - offset + 1) % (offset_max - offset)) + offset;
92 start = &WR_CELL(cell_id)->vpool[WR_CELL(cell_id)->vertex_list[i]];
93 end = &WR_CELL(cell_id)->vpool[WR_CELL(cell_id)->vertex_list[j]];
95 cEdgeContact edgeContact(*start, *end);
96 mxs_real edge_dist = fabs(edgeContact.GetDist(sphere_loc) - sphere_radius);
97 if ((best_edge_dist < 0.0) || (edge_dist < best_edge_dist))
99 best_edge_dist = edge_dist;
100 mx_copy_vec(&normal, &edgeContact.GetNormal(sphere_loc));
104 pPoly = pPoly->GetNext();
107 if (best_edge_dist < 0.0)
109 Warning(("No edge found for normal computation!\n"));
110 mx_unit_vec(&normal, 0); // uh, why not
111 return FALSE;
114 break;
117 default:
119 if ((poly_count < 0) || (poly_count > 20))
121 Warning(("Suspicious number of polys in list: %d\n", poly_count));
122 return FALSE;
125 mxs_vector *vertex;
126 int cell_id, poly_id;
127 int offset, offset_max;
128 int i;
129 mxs_real best_vertex_dist = -1.0;
131 pPoly = GetFirst();
132 while (pPoly != NULL)
134 cell_id = pPoly->GetCellID();
135 poly_id = pPoly->GetPolyID();
137 // Find starting offset of poly
138 offset = 0;
139 for (i=0; i<poly_id; i++)
140 offset += WR_CELL(cell_id)->poly_list[i].num_vertices;
142 offset_max = offset + WR_CELL(cell_id)->poly_list[poly_id].num_vertices;
144 // Find a vertex that is the right distance from the collision point
145 for (i=offset; i<offset_max; i++)
147 vertex = &WR_CELL(cell_id)->vpool[WR_CELL(cell_id)->vertex_list[i]];
149 mxs_real vertex_dist = fabs(mx_dist_vec(vertex, &sphere_loc) - sphere_radius);
151 if ((best_vertex_dist < 0.0) || (vertex_dist < best_vertex_dist))
153 best_vertex_dist = vertex_dist;
154 mx_sub_vec(&normal, &sphere_loc, vertex);
158 pPoly = pPoly->GetNext();
161 if (best_vertex_dist < 0.0)
163 Warning(("No edge found for normal computation!\n"));
164 mx_unit_vec(&normal, 0); // uh, why not
165 return FALSE;
168 if (mx_mag2_vec(&normal) > 0.0001)
169 mx_normeq_vec(&normal);
171 break;
175 return TRUE;
178 ///////////////////////////////////////
180 // Find a poly in a list
183 BOOL cPhysTerrPolyList::Find(int cellID, int polyID, cPhysTerrPoly ** ppTerrPoly) const
185 cPhysTerrPoly *pPoly = GetFirst();
187 while (pPoly != NULL)
189 if ((pPoly->GetCellID() == cellID) && (pPoly->GetPolyID() == polyID))
191 *ppTerrPoly = pPoly;
192 return TRUE;
194 pPoly = pPoly->GetNext();
197 return FALSE;
200 ///////////////////////////////////////////////////////////////////////////////
202 // CLASS: cPhysTerrPoly
205 #include <wr.h>
206 #include <memall.h>
207 #include <dbmem.h> // must be last header!
209 int cPhysTerrPoly::GetPlaneID(void) const
211 return WR_CELL(m_cellID)->poly_list[m_polyID].planeid;
214 ///////////////////////////////////////
216 const mxs_vector & cPhysTerrPoly::GetNormal(void) const
218 return WR_CELL(m_cellID)->plane_list[GetPlaneID()].normal;
221 ///////////////////////////////////////
223 mxs_real cPhysTerrPoly::GetPlaneConstant(void) const
225 return WR_CELL(m_cellID)->plane_list[GetPlaneID()].plane_constant;
228 ///////////////////////////////////////////////////////////////////////////////
230 // CLASS: cPhysTerrPolyArray
233 ///////////////////////////////////////////////////////////////////////////////