IceIndexedTriangle.cpp
Go to the documentation of this file.
00001 
00002 
00008 
00009 
00011 // Precompiled Header
00012 #include "Stdafx.h"
00013 
00014 using namespace IceMaths;
00015 
00017 
00025 
00026 
00028 
00031 
00032 void IndexedTriangle::Flip()
00033 {
00034         Swap(mVRef[1], mVRef[2]);
00035 }
00036 
00038 
00043 
00044 float IndexedTriangle::Area(const Point* verts) const
00045 {
00046         if(!verts)      return 0.0f;
00047         const Point& p0 = verts[0];
00048         const Point& p1 = verts[1];
00049         const Point& p2 = verts[2];
00050         return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f;
00051 }
00052 
00054 
00059 
00060 float IndexedTriangle::Perimeter(const Point* verts)    const
00061 {
00062         if(!verts)      return 0.0f;
00063         const Point& p0 = verts[0];
00064         const Point& p1 = verts[1];
00065         const Point& p2 = verts[2];
00066         return          p0.Distance(p1)
00067                         +       p0.Distance(p2)
00068                         +       p1.Distance(p2);
00069 }
00070 
00072 
00077 
00078 float IndexedTriangle::Compacity(const Point* verts) const
00079 {
00080         if(!verts)      return 0.0f;
00081         float P = Perimeter(verts);
00082         if(P==0.0f)     return 0.0f;
00083         return (4.0f*PI*Area(verts)/(P*P));
00084 }
00085 
00087 
00092 
00093 void IndexedTriangle::Normal(const Point* verts, Point& normal) const
00094 {
00095         if(!verts)      return;
00096 
00097         const Point& p0 = verts[mVRef[0]];
00098         const Point& p1 = verts[mVRef[1]];
00099         const Point& p2 = verts[mVRef[2]];
00100         normal = ((p2-p1)^(p0-p1)).Normalize();
00101 }
00102 
00104 
00109 
00110 void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal)     const
00111 {
00112         if(!verts)      return;
00113 
00114         const Point& p0 = verts[mVRef[0]];
00115         const Point& p1 = verts[mVRef[1]];
00116         const Point& p2 = verts[mVRef[2]];
00117         normal = ((p2-p1)^(p0-p1));
00118 }
00119 
00121 
00126 
00127 void IndexedTriangle::Center(const Point* verts, Point& center) const
00128 {
00129         if(!verts)      return;
00130 
00131         const Point& p0 = verts[mVRef[0]];
00132         const Point& p1 = verts[mVRef[1]];
00133         const Point& p2 = verts[mVRef[2]];
00134         center = (p0+p1+p2)*INV3;
00135 }
00136 
00138 
00143 
00144 void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal) const
00145 {
00146         if(!verts)      return;
00147 
00148         const Point& p0 = verts[mVRef[0]];
00149         const Point& p1 = verts[mVRef[1]];
00150         const Point& p2 = verts[mVRef[2]];
00151         Point Center = (p0+p1+p2)*INV3;
00152         normal = Center + ((p2-p1)^(p0-p1)).Normalize();
00153 }
00154 
00156 
00161 
00162 void IndexedTriangle::RandomPoint(const Point* verts, Point& random)    const
00163 {
00164         if(!verts)      return;
00165 
00166         // Random barycentric coords
00167         float Alpha     = UnitRandomFloat();
00168         float Beta      = UnitRandomFloat();
00169         float Gamma     = UnitRandomFloat();
00170         float OneOverTotal = 1.0f / (Alpha + Beta + Gamma);
00171         Alpha   *= OneOverTotal;
00172         Beta    *= OneOverTotal;
00173         Gamma   *= OneOverTotal;
00174 
00175         const Point& p0 = verts[mVRef[0]];
00176         const Point& p1 = verts[mVRef[1]];
00177         const Point& p2 = verts[mVRef[2]];
00178         random = Alpha*p0 + Beta*p1 + Gamma*p2;
00179 }
00180 
00182 
00188 
00189 bool IndexedTriangle::IsVisible(const Point* verts, const Point& source)        const
00190 {
00191         // Checkings
00192         if(!verts)      return false;
00193 
00194         const Point& p0 = verts[mVRef[0]];
00195         const Point& p1 = verts[mVRef[1]];
00196         const Point& p2 = verts[mVRef[2]];
00197 
00198         // Compute denormalized normal
00199         Point Normal = (p2 - p1)^(p0 - p1);
00200 
00201         // Backface culling
00202         return (Normal | source) >= 0.0f;
00203 
00204 // Same as:
00205 //      Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
00206 //      return PL.Distance(source) > PL.d;
00207 }
00208 
00210 
00216 
00217 bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source)  const
00218 {
00219         // Checkings
00220         if(!verts)      return false;
00221 
00222         const Point& p0 = verts[mVRef[0]];
00223         const Point& p1 = verts[mVRef[1]];
00224         const Point& p2 = verts[mVRef[2]];
00225 
00226         // Compute base
00227 //      Point Base = (p0 + p1 + p2)*INV3;
00228 
00229         // Compute denormalized normal
00230         Point Normal = (p2 - p1)^(p0 - p1);
00231 
00232         // Backface culling
00233 //      return (Normal | (source - Base)) >= 0.0f;
00234         return (Normal | (source - p0)) >= 0.0f;
00235 
00236 // Same as: (but a bit faster)
00237 //      Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
00238 //      return PL.Distance(source)>0.0f;
00239 }
00240 
00242 
00248 
00249 float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view) const
00250 {
00251         if(!verts)      return 0.0f;
00252         // Occlusion potential: -(A * (N|V) / d^2)
00253         // A = polygon area
00254         // N = polygon normal
00255         // V = view vector
00256         // d = distance viewpoint-center of polygon
00257 
00258         float A = Area(verts);
00259         Point N;        Normal(verts, N);
00260         Point C;        Center(verts, C);
00261         float d = view.Distance(C);
00262         return -(A*(N|view))/(d*d);
00263 }
00264 
00266 
00272 
00273 bool IndexedTriangle::ReplaceVertex(udword oldref, udword newref)
00274 {
00275                         if(mVRef[0]==oldref)    { mVRef[0] = newref; return true; }
00276         else    if(mVRef[1]==oldref)    { mVRef[1] = newref; return true; }
00277         else    if(mVRef[2]==oldref)    { mVRef[2] = newref; return true; }
00278         return false;
00279 }
00280 
00282 
00286 
00287 bool IndexedTriangle::IsDegenerate()    const
00288 {
00289         if(mVRef[0]==mVRef[1])  return true;
00290         if(mVRef[1]==mVRef[2])  return true;
00291         if(mVRef[2]==mVRef[0])  return true;
00292         return false;
00293 }
00294 
00296 
00301 
00302 bool IndexedTriangle::HasVertex(udword ref)     const
00303 {
00304         if(mVRef[0]==ref)       return true;
00305         if(mVRef[1]==ref)       return true;
00306         if(mVRef[2]==ref)       return true;
00307         return false;
00308 }
00309 
00311 
00317 
00318 bool IndexedTriangle::HasVertex(udword ref, udword* index)      const
00319 {
00320         if(mVRef[0]==ref)       { *index = 0;   return true; }
00321         if(mVRef[1]==ref)       { *index = 1;   return true; }
00322         if(mVRef[2]==ref)       { *index = 2;   return true; }
00323         return false;
00324 }
00325 
00327 
00333 
00334 ubyte IndexedTriangle::FindEdge(udword vref0, udword vref1)     const
00335 {
00336                         if(mVRef[0]==vref0 && mVRef[1]==vref1)  return 0;
00337         else    if(mVRef[0]==vref1 && mVRef[1]==vref0)  return 0;
00338         else    if(mVRef[0]==vref0 && mVRef[2]==vref1)  return 1;
00339         else    if(mVRef[0]==vref1 && mVRef[2]==vref0)  return 1;
00340         else    if(mVRef[1]==vref0 && mVRef[2]==vref1)  return 2;
00341         else    if(mVRef[1]==vref1 && mVRef[2]==vref0)  return 2;
00342         return 0xff;
00343 }
00344 
00346 
00352 
00353 udword IndexedTriangle::OppositeVertex(udword vref0, udword vref1)      const
00354 {
00355                         if(mVRef[0]==vref0 && mVRef[1]==vref1)  return mVRef[2];
00356         else    if(mVRef[0]==vref1 && mVRef[1]==vref0)  return mVRef[2];
00357         else    if(mVRef[0]==vref0 && mVRef[2]==vref1)  return mVRef[1];
00358         else    if(mVRef[0]==vref1 && mVRef[2]==vref0)  return mVRef[1];
00359         else    if(mVRef[1]==vref0 && mVRef[2]==vref1)  return mVRef[0];
00360         else    if(mVRef[1]==vref1 && mVRef[2]==vref0)  return mVRef[0];
00361         return INVALID_ID;
00362 }
00363 
00365 
00376 
00377 void IndexedTriangle::GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const
00378 {
00379         if(edgenb==0)
00380         {
00381                 vref0 = mVRef[0];
00382                 vref1 = mVRef[1];
00383                 vref2 = mVRef[2];
00384         }
00385         else if(edgenb==1)
00386         {
00387                 vref0 = mVRef[0];
00388                 vref1 = mVRef[2];
00389                 vref2 = mVRef[1];
00390         }
00391         else if(edgenb==2)
00392         {
00393                 vref0 = mVRef[1];
00394                 vref1 = mVRef[2];
00395                 vref2 = mVRef[0];
00396         }
00397 }
00398 
00400 
00405 
00406 float IndexedTriangle::MinEdgeLength(const Point* verts)        const
00407 {
00408         if(!verts)      return 0.0f;
00409 
00410         float Min = MAX_FLOAT;
00411         float Length01 = verts[0].Distance(verts[1]);
00412         float Length02 = verts[0].Distance(verts[2]);
00413         float Length12 = verts[1].Distance(verts[2]);
00414         if(Length01 < Min)      Min = Length01;
00415         if(Length02 < Min)      Min = Length02;
00416         if(Length12 < Min)      Min = Length12;
00417         return Min;
00418 }
00419 
00421 
00426 
00427 float IndexedTriangle::MaxEdgeLength(const Point* verts)        const
00428 {
00429         if(!verts)      return 0.0f;
00430 
00431         float Max = MIN_FLOAT;
00432         float Length01 = verts[0].Distance(verts[1]);
00433         float Length02 = verts[0].Distance(verts[2]);
00434         float Length12 = verts[1].Distance(verts[2]);
00435         if(Length01 > Max)      Max = Length01;
00436         if(Length02 > Max)      Max = Length02;
00437         if(Length12 > Max)      Max = Length12;
00438         return Max;
00439 }
00440 
00442 
00449 
00450 void IndexedTriangle::ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx)    const
00451 {
00452         // Checkings
00453         if(!verts)      return;
00454 
00455         // Get face in local or global space
00456         const Point& p0 = verts[mVRef[0]];
00457         const Point& p1 = verts[mVRef[1]];
00458         const Point& p2 = verts[mVRef[2]];
00459 
00460         // Compute point coordinates
00461         pt = (1.0f - u - v)*p0 + u*p1 + v*p2;
00462 
00463         // Compute nearest vertex if needed
00464         if(nearvtx)
00465         {
00466                 // Compute distance vector
00467                 Point d(p0.SquareDistance(pt),  // Distance^2 from vertex 0 to point on the face
00468                                 p1.SquareDistance(pt),  // Distance^2 from vertex 1 to point on the face
00469                                 p2.SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face
00470 
00471                 // Get smallest distance
00472                 *nearvtx = mVRef[d.SmallestAxis()];
00473         }
00474 }
00475 
00476         //**************************************
00477         // Angle between two vectors (in radians)
00478         // we use this formula
00479         // uv = |u||v| cos(u,v)
00480         // u  ^ v  = w
00481         // |w| = |u||v| |sin(u,v)|
00482         //**************************************
00483         float Angle(const Point& u, const Point& v)
00484         {
00485                 float NormU = u.Magnitude();    // |u|
00486                 float NormV = v.Magnitude();    // |v|
00487                 float Product = NormU*NormV;    // |u||v|
00488                 if(Product==0.0f)       return 0.0f;
00489                 float OneOverProduct = 1.0f / Product;
00490 
00491                 // Cosinus
00492                 float Cosinus = (u|v) * OneOverProduct;
00493 
00494                 // Sinus
00495                 Point w = u^v;
00496                 float NormW = w.Magnitude();
00497 
00498                 float AbsSinus = NormW * OneOverProduct;
00499 
00500                 // Remove degeneracy
00501                 if(AbsSinus > 1.0f) AbsSinus = 1.0f;
00502                 if(AbsSinus < -1.0f) AbsSinus = -1.0f;
00503 
00504                 if(Cosinus>=0.0f)       return asinf(AbsSinus);
00505                 else                            return (PI-asinf(AbsSinus));
00506         }
00507 
00509 
00515 
00516 float IndexedTriangle::Angle(const IndexedTriangle& tri, const Point* verts)    const
00517 {
00518         // Checkings
00519         if(!verts)      return 0.0f;
00520 
00521         // Compute face normals
00522         Point n0, n1;
00523         Normal(verts, n0);
00524         tri.Normal(verts, n1);
00525 
00526         // Compute angle
00527         float dp = n0|n1;
00528         if(dp>1.0f)             return 0.0f;
00529         if(dp<-1.0f)    return PI;
00530         return acosf(dp);
00531 
00532 //      return ::Angle(n0,n1);
00533 }
00534 
00536 
00541 
00542 bool IndexedTriangle::Equal(const IndexedTriangle& tri) const
00543 {
00544         // Test all vertex references
00545         return (HasVertex(tri.mVRef[0]) && 
00546                         HasVertex(tri.mVRef[1]) &&
00547                         HasVertex(tri.mVRef[2]));
00548 }


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Sun Apr 2 2017 03:43:54