Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IceTriangle.cpp
Go to the documentation of this file.
1 
8 
11 // Precompiled Header
12 #include "Stdafx.h"
13 
14 
15 using namespace Opcode;
16 
18 
26 
28 static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon)
29 {
30  // Compute distance from current vertex to the plane
31  float Dist = plane.Distance(v);
32  // Compute side:
33  // 1 = the vertex is on the positive side of the plane
34  // -1 = the vertex is on the negative side of the plane
35  // 0 = the vertex is on the plane (within epsilon)
36  return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0;
37 }
38 
40 
43 void Triangle::Flip()
45 {
46  Point Tmp = mVerts[1];
47  mVerts[1] = mVerts[2];
48  mVerts[2] = Tmp;
49 }
50 
52 
56 float Triangle::Area() const
58 {
59  const Point& p0 = mVerts[0];
60  const Point& p1 = mVerts[1];
61  const Point& p2 = mVerts[2];
62  return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f;
63 }
64 
66 
70 float Triangle::Perimeter() const
72 {
73  const Point& p0 = mVerts[0];
74  const Point& p1 = mVerts[1];
75  const Point& p2 = mVerts[2];
76  return p0.Distance(p1)
77  + p0.Distance(p2)
78  + p1.Distance(p2);
79 }
80 
82 
86 float Triangle::Compacity() const
88 {
89  float P = Perimeter();
90  if(P==0.0f) return 0.0f;
91  return (4.0f*PI*Area()/(P*P));
92 }
93 
95 
99 void Triangle::Normal(Point& normal) const
101 {
102  const Point& p0 = mVerts[0];
103  const Point& p1 = mVerts[1];
104  const Point& p2 = mVerts[2];
105  normal = ((p0 - p1)^(p0 - p2)).Normalize();
106 }
107 
109 
113 void Triangle::DenormalizedNormal(Point& normal) const
115 {
116  const Point& p0 = mVerts[0];
117  const Point& p1 = mVerts[1];
118  const Point& p2 = mVerts[2];
119  normal = ((p0 - p1)^(p0 - p2));
120 }
121 
123 
127 void Triangle::Center(Point& center) const
129 {
130  const Point& p0 = mVerts[0];
131  const Point& p1 = mVerts[1];
132  const Point& p2 = mVerts[2];
133  center = (p0 + p1 + p2)*INV3;
134 }
135 
137 {
138  bool Pos = false, Neg = false;
139 
140  // Loop through all vertices
141  for(udword i=0;i<3;i++)
142  {
143  // Compute side:
144  sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon);
145 
146  if (Side < 0) Neg = true;
147  else if (Side > 0) Pos = true;
148  }
149 
150  if (!Pos && !Neg) return TRI_ON_PLANE;
151  else if (Pos && Neg) return TRI_INTERSECT;
152  else if (Pos && !Neg) return TRI_PLUS_SPACE;
153  else if (!Pos && Neg) return TRI_MINUS_SPACE;
154 
155  // What?!
156  return TRI_FORCEDWORD;
157 }
158 
160 
164 /*
166 void Triangle::ComputeMoment(Moment& m)
167 {
168  // Compute the area of the triangle
169  m.mArea = Area();
170 
171  // Compute the centroid
172  Center(m.mCentroid);
173 
174  // Second-order components. Handle zero-area faces.
175  Point& p = mVerts[0];
176  Point& q = mVerts[1];
177  Point& r = mVerts[2];
178  if(m.mArea==0.0f)
179  {
180  // This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the
181  // sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices.
182  m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x);
183  m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y);
184  m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z);
185  m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y);
186  m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z);
187  m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z);
188  m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
189  m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
190  m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
191  }
192  else
193  {
194  const float OneOverTwelve = 1.0f / 12.0f;
195  m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve;
196  m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve;
197  m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve;
198  m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve;
199  m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve;
200  m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve;
201  m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
202  m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
203  m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
204  }
205 }
206 */
207 
209 
213 float Triangle::MinEdgeLength() const
215 {
216  float Min = MAX_FLOAT;
217  float Length01 = mVerts[0].Distance(mVerts[1]);
218  float Length02 = mVerts[0].Distance(mVerts[2]);
219  float Length12 = mVerts[1].Distance(mVerts[2]);
220  if(Length01 < Min) Min = Length01;
221  if(Length02 < Min) Min = Length02;
222  if(Length12 < Min) Min = Length12;
223  return Min;
224 }
225 
227 
231 float Triangle::MaxEdgeLength() const
233 {
234  float Max = MIN_FLOAT;
235  float Length01 = mVerts[0].Distance(mVerts[1]);
236  float Length02 = mVerts[0].Distance(mVerts[2]);
237  float Length12 = mVerts[1].Distance(mVerts[2]);
238  if(Length01 > Max) Max = Length01;
239  if(Length02 > Max) Max = Length02;
240  if(Length12 > Max) Max = Length12;
241  return Max;
242 }
243 
245 
251 void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const
253 {
254  // Compute point coordinates
255  pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2];
256 
257  // Compute nearest vertex if needed
258  if(nearvtx)
259  {
260  // Compute distance vector
261  Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face
262  mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face
263  mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face
264 
265  // Get smallest distance
266  *nearvtx = d.SmallestAxis();
267  }
268 }
269 
270 void Triangle::Inflate(float fat_coeff, bool constant_border)
271 {
272  // Compute triangle center
273  Point TriangleCenter;
274  Center(TriangleCenter);
275 
276  // Don't normalize?
277  // Normalize => add a constant border, regardless of triangle size
278  // Don't => add more to big triangles
279  for(udword i=0;i<3;i++)
280  {
281  Point v = mVerts[i] - TriangleCenter;
282 
283  if(constant_border) v.Normalize();
284 
285  mVerts[i] += v * fat_coeff;
286  }
287 }
288