Ignore:
Timestamp:
09/07/08 13:44:28 (16 years ago)
Author:
mattausch
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.cpp

    r2802 r2911  
     1#include "AxisAlignedBox3.h" 
     2#include "Plane3.h" 
     3#include "Polygon3.h" 
     4#include "Polyhedron.h" 
     5 
    16#include <cassert> 
    27#include <iostream> 
    3 #include "AxisAlignedBox3.h" 
    4 #include "Plane3.h" 
    5  
    68 
    79using namespace std; 
     
    5052        Minimize(mMin, newpt); 
    5153        Maximize(mMax, newpt); 
     54} 
     55 
     56 
     57void AxisAlignedBox3::Include(const Polygon3 &newpoly) 
     58{ 
     59        VertexArray::const_iterator it, it_end = newpoly.mVertices.end(); 
     60 
     61        for (it = newpoly.mVertices.begin(); it != it_end; ++ it) 
     62                Include(*it); 
     63} 
     64 
     65 
     66void AxisAlignedBox3::Include(const PolygonContainer &polys) 
     67{ 
     68        PolygonContainer::const_iterator it, it_end = polys.end(); 
     69 
     70        for (it = polys.begin(); it != it_end; ++ it) 
     71                Include(*(*it)); 
    5272} 
    5373 
     
    10261046} 
    10271047 
    1028 } 
    1029  
     1048 
     1049struct VertexData 
     1050{ 
     1051        Vector3 mVertex; 
     1052        float mAngle; 
     1053         
     1054        VertexData(Vector3 vtx, float angle): mVertex(vtx), mAngle(angle) 
     1055        {} 
     1056 
     1057        bool operator<(const VertexData &b) const  
     1058        { 
     1059                return mAngle > b.mAngle; 
     1060        } 
     1061}; 
     1062 
     1063// TODO: use a table to avoid normal and distance computations 
     1064Polygon3 *AxisAlignedBox3::CrossSection(const Plane3 &plane) const 
     1065{ 
     1066        Polygon3 *planePoly = new Polygon3(); 
     1067         
     1068        int side[8]; 
     1069        bool onFrontSide = false, onBackSide = false; 
     1070         
     1071        Vector3 vtx; 
     1072         
     1073        ////////////// 
     1074        //-- compute classification of vertices 
     1075 
     1076        for (int i = 0; i < 8; ++i) 
     1077        { 
     1078                GetVertex(i, vtx); 
     1079                side[i] = plane.Side(vtx); 
     1080                if (side[i] > 0) 
     1081                        onFrontSide = true; 
     1082                else if (side[i] < 0) 
     1083                        onBackSide = true; 
     1084                else // vertex coincident => push_back 
     1085                        planePoly->mVertices.push_back(vtx); 
     1086        } 
     1087 
     1088        /////////// 
     1089        //-- find intersections 
     1090 
     1091        if (onFrontSide && onBackSide) 
     1092        { 
     1093                Vector3 ptA, ptB; 
     1094                for (int i = 0; i < 12; ++ i) 
     1095                { 
     1096                        int aIdx, bIdx; 
     1097                        GetEdge(i, aIdx, bIdx); 
     1098 
     1099                        ptA = GetVertex(aIdx); 
     1100                        ptB = GetVertex(bIdx); 
     1101 
     1102                        int sideA = side[aIdx]; 
     1103                        int sideB = side[bIdx]; 
     1104 
     1105                        if (((sideA > 0) && (sideB < 0)) || (sideA < 0) && (sideB > 0)) 
     1106                                planePoly->mVertices.push_back(plane.FindIntersection(ptA, ptB));        
     1107                } 
     1108        } 
     1109 
     1110        // order intersections   
     1111        if (planePoly->mVertices.size() > 3) 
     1112        { 
     1113                Vector3 centerOfMass(0); 
     1114 
     1115                int i; 
     1116                // compute center of mass 
     1117                for (i = 0; i < (int)planePoly->mVertices.size(); ++ i) 
     1118                        centerOfMass += planePoly->mVertices[i]; 
     1119                 
     1120                centerOfMass /= (float)planePoly->mVertices.size(); 
     1121 
     1122                vector<VertexData> vertexData; 
     1123                Vector3 refVec = Normalize(centerOfMass - planePoly->mVertices[0]); 
     1124 
     1125                // compute angle to reference point 
     1126                for (i = 1; i < (int)planePoly->mVertices.size(); ++ i) 
     1127                { 
     1128                    float angle =  
     1129                      Angle(refVec, centerOfMass - planePoly->mVertices[i], plane.mNormal); 
     1130                     
     1131                    vertexData.push_back(VertexData(planePoly->mVertices[i], angle)); 
     1132                } 
     1133                 
     1134                std::stable_sort(vertexData.begin(), vertexData.end()); 
     1135 
     1136                // update vertices 
     1137                for (i = 1; i < (int)planePoly->mVertices.size(); ++ i) 
     1138                        planePoly->mVertices[i] = vertexData[i - 1].mVertex; 
     1139        } 
     1140        else if (planePoly->mVertices.size() == 3) 
     1141        { 
     1142                // fix orientation if needed 
     1143                if (DotProd(planePoly->GetNormal(), plane.mNormal) < 0) 
     1144                { 
     1145                        Vector3 v = planePoly->mVertices[1]; 
     1146                        planePoly->mVertices[1] = planePoly->mVertices[2]; 
     1147                        planePoly->mVertices[2] = v; 
     1148                } 
     1149        } 
     1150         
     1151        return planePoly; 
     1152} 
     1153 
     1154 
     1155Plane3 AxisAlignedBox3::GetPlane(const int face) const 
     1156{ 
     1157        switch (face)  
     1158        { 
     1159         
     1160        case 0: 
     1161                return Plane3(Vector3(-1, 0, 0), mMin); 
     1162        case 1:  
     1163                return Plane3(Vector3(1, 0, 0), mMax); 
     1164        case 2: 
     1165                return Plane3(Vector3(0, -1, 0), mMin); 
     1166        case 3: 
     1167                return Plane3(Vector3(0, 1, 0), mMax); 
     1168        case 4: 
     1169                return Plane3(Vector3(0, 0, -1), mMin); 
     1170        case 5: 
     1171                return Plane3(Vector3(0, 0, 1), mMax); 
     1172        } 
     1173 
     1174        // should not come here 
     1175        return Plane3(); 
     1176} 
     1177 
     1178 
     1179int AxisAlignedBox3::Side(const Plane3 &plane) const 
     1180{ 
     1181        int s = 0; 
     1182        // if exactly one of the vertices lies on the plane  
     1183        // and the others are on the same side, the plane is tangent 
     1184        // to the box on either side and not intersecting 
     1185        for (int i = 0; i < 8; ++ i) 
     1186        { 
     1187                Vector3 pt; 
     1188                GetVertex(i, pt); 
     1189 
     1190                int side = plane.Side(pt); 
     1191 
     1192                if (side != 0) 
     1193                { 
     1194                        if (side == -s) 
     1195                                return 0; // sign changed => intersects 
     1196 
     1197                        s = side; 
     1198                } 
     1199        } 
     1200 
     1201        return s; 
     1202} 
     1203 
     1204 
     1205Polyhedron *AxisAlignedBox3::CalcIntersection(Polyhedron *polyhedron) const 
     1206{ 
     1207        Polyhedron *oldPolyhedron = new Polyhedron(*polyhedron); 
     1208 
     1209        Polyhedron *newPolyhedron = NULL; 
     1210 
     1211        for (int i = 0; i < 6; ++ i) 
     1212        { 
     1213                Polyhedron *newPolyhedron = oldPolyhedron->CalcIntersection(GetPlane(i)); 
     1214                DEL_PTR(oldPolyhedron); 
     1215 
     1216                if (!newPolyhedron) 
     1217                        return NULL; 
     1218        } 
     1219 
     1220        return newPolyhedron; 
     1221} 
     1222 
     1223 
     1224} 
     1225 
Note: See TracChangeset for help on using the changeset viewer.