Ignore:
Timestamp:
11/09/05 15:22:39 (19 years ago)
Author:
mattausch
Message:

fixed bug in bsp geometry construction

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp

    r394 r396  
    697697        //-- terminate traversal   
    698698        if (((int)tData.mPolygons->size() <= sTermMaxPolygons) ||  
    699                 ((int)tData.mRays->size() <= sTermMaxRays)         || 
    700                 ((int)tData.mPvs <= sTermMinPvs)            || 
     699                ((int)tData.mRays->size() <= sTermMaxRays) || 
     700                (tData.mPvs <= sTermMinPvs) || 
    701701                 (tData.mDepth >= sTermMaxDepth)) 
    702702                 
     
    13431343                {        
    13441344                        // construct child geometry with regard to the candidate split plane 
    1345                         frontData.mCell = cell.ConstructChild(*this, candidatePlane, true); 
    1346                         backData.mCell = cell.ConstructChild(*this, candidatePlane, false); 
    1347  
     1345                        frontData.mCell = new BspNodeGeometry(); 
     1346                        backData.mCell = new BspNodeGeometry(); 
     1347 
     1348                        cell.SplitGeometry(*frontData.mCell, *backData.mCell, *this, candidatePlane); 
     1349                 
    13481350                        pFront = frontData.mArea = frontData.mCell->GetArea(); 
    13491351                        pBack = backData.mArea = backData.mCell->GetArea(); 
     
    20082010} 
    20092011 
    2010 void BspTree::ExtractSplitPlanes(BspNode *n,  
    2011                                                                  vector<Plane3> &planes,  
    2012                                                                  vector<bool> &sides) const 
     2012void BspTree::ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const 
    20132013{ 
    20142014        BspNode *lastNode; 
     
    20242024                { 
    20252025                        BspInterior *interior = dynamic_cast<BspInterior *>(n); 
    2026  
    2027                         planes.push_back(* dynamic_cast<BspInterior *>(interior)->GetPlane()); 
    2028                         sides.push_back(interior->mFront == lastNode); 
     2026                        Plane3 halfSpace = *dynamic_cast<BspInterior *>(interior)->GetPlane(); 
     2027 
     2028            if (interior->mFront != lastNode) 
     2029                                halfSpace.ReverseOrientation(); 
     2030 
     2031                        halfSpaces.push_back(halfSpace); 
    20292032                } 
    20302033        } 
     
    20342037void BspTree::ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const 
    20352038{ 
    2036         stack<BspNode *> tStack; 
    2037  
    2038         vector<Plane3> planes; 
    2039         vector<bool> sides; 
    2040  
    2041         ExtractSplitPlanes(n, cell.mPlanes, cell.mSides); 
     2039        PolygonContainer polys; 
     2040        ConstructGeometry(n, polys); 
     2041        cell.mPolys = polys; 
     2042} 
     2043 
     2044void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const 
     2045{ 
     2046        vector<BspLeaf *> leaves = vc->mBspLeaves; 
     2047 
     2048        vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
     2049 
     2050        for (it = leaves.begin(); it != it_end; ++ it) 
     2051                ConstructGeometry(*it, cell); 
     2052} 
     2053 
     2054 
     2055void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const 
     2056{ 
     2057        vector<Plane3> halfSpaces; 
     2058        ExtractHalfSpaces(n, halfSpaces); 
    20422059 
    20432060        PolygonContainer candidatePolys; 
    20442061 
    2045         // bounded planes are added to the polygons 
    2046         for (int i = 0; i < (int)cell.mPlanes.size(); ++ i) 
    2047         { 
    2048                 candidatePolys.push_back(GetBoundingBox().CrossSection(cell.mPlanes[i])); 
     2062        // bounded planes are added to the polygons (reverse polygons 
     2063        // as they have to be outfacing 
     2064        for (int i = 0; i < (int)halfSpaces.size(); ++ i) 
     2065        { 
     2066                Polygon3 *p = GetBoundingBox().CrossSection(halfSpaces[i]); 
     2067                 
     2068                if (p->Valid()) 
     2069                { 
     2070                        candidatePolys.push_back(p->CreateReversePolygon()); 
     2071                        DEL_PTR(p); 
     2072                } 
    20492073        } 
    20502074 
     
    20622086        for (int i = 0; i < (int)candidatePolys.size(); ++ i) 
    20632087        { 
    2064                 bool inside = true; 
    2065  
    20662088                // polygon is split by all other planes 
    2067                 for (int j = 0; (j < cell.mPlanes.size()) && inside; ++ j) 
    2068                 { 
    2069                         if (i == j) // same plane 
     2089                for (int j = 0; (j < (int)halfSpaces.size()) && candidatePolys[i]; ++ j) 
     2090                { 
     2091                        if (i == j) // polygon and plane are coincident 
    20702092                                continue; 
    20712093 
     
    20732095                        Polygon3 *frontPoly, *backPoly; 
    20742096 
    2075                         const int cf = candidatePolys[i]->ClassifyPlane(cell.mPlanes[j]); 
     2097                        const int cf = candidatePolys[i]->ClassifyPlane(halfSpaces[j]); 
    20762098                         
    20772099                        switch (cf) 
     
    20802102                                        frontPoly = new Polygon3(); 
    20812103                                        backPoly = new Polygon3(); 
    2082                                  
    2083                                         candidatePolys[i]->Split(cell.mPlanes[j], *frontPoly,  
     2104 
     2105                                        candidatePolys[i]->Split(halfSpaces[j], *frontPoly,  
    20842106                                                                                         *backPoly, splitPts); 
     2107 
    20852108                                        DEL_PTR(candidatePolys[i]); 
    20862109 
    2087                                         if(sides[j] == true) 
    2088                                         { 
     2110                                        if (frontPoly->Valid()) 
    20892111                                                candidatePolys[i] = frontPoly; 
    2090                                                 DEL_PTR(backPoly); 
    2091                                         } 
    20922112                                        else 
    2093                                         { 
    2094                                                 candidatePolys[i] = backPoly; 
    20952113                                                DEL_PTR(frontPoly); 
    2096                                         } 
    2097                                          
     2114 
     2115                                        DEL_PTR(backPoly); 
    20982116                                        break; 
    2099  
    21002117                                case Polygon3::BACK_SIDE: 
    2101                                         if (cell.mSides[j])  
    2102                                                 inside = false; 
     2118                                        DEL_PTR(candidatePolys[i]); 
    21032119                                        break; 
     2120                                // just take polygon as it is 
    21042121                                case Polygon3::FRONT_SIDE: 
    2105                                         if (!cell.mSides[j]) 
    2106                                                 inside = false; 
    2107                                         break; 
    21082122                                case Polygon3::COINCIDENT: 
    2109                                         break; 
    21102123                                default: 
    21112124                                        break; 
     
    21132126                } 
    21142127                 
    2115                 if (inside) 
    2116                         cell.mPolys.push_back(candidatePolys[i]); 
    2117                 else 
    2118                         DEL_PTR(candidatePolys[i]); 
    2119         } 
    2120 } 
    2121  
    2122 void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const 
    2123 { 
    2124         stack<BspNode *> tStack; 
    2125  
    2126         vector<Plane3> planes; 
    2127         vector<bool> sides; 
    2128  
    2129         ExtractSplitPlanes(n, planes, sides); 
    2130  
    2131         PolygonContainer candidatePolys; 
    2132  
    2133         // bounded planes are added to the polygons 
    2134         for (int i = 0; i < (int)planes.size(); ++ i) 
    2135         { 
    2136                 candidatePolys.push_back(GetBoundingBox().CrossSection(planes[i])); 
    2137         } 
    2138  
    2139         // add faces of bounding box (also could be faces of the cell) 
    2140         for (int i = 0; i < 6; ++ i) 
    2141         { 
    2142                 VertexContainer vertices; 
    2143          
    2144                 for (int j = 0; j < 4; ++ j) 
    2145                         vertices.push_back(mBox.GetFace(i).mVertices[j]); 
    2146  
    2147                 candidatePolys.push_back(new Polygon3(vertices)); 
    2148         } 
    2149  
    2150         for (int i = 0; i < (int)candidatePolys.size(); ++ i) 
    2151         { 
    2152                 bool inside = true; 
    2153  
    2154                 // polygon is split by all other planes 
    2155                 for (int j = 0; (j < planes.size()) && inside; ++ j) 
    2156                 { 
    2157                         if (i == j) // same plane 
    2158                                 continue; 
    2159  
    2160                         VertexContainer splitPts; 
    2161                         Polygon3 *frontPoly, *backPoly; 
    2162  
    2163                         const int cf = candidatePolys[i]->ClassifyPlane(planes[j]); 
    2164                          
    2165                         switch (cf) 
    2166                         { 
    2167                                 case Polygon3::SPLIT: 
    2168                                         frontPoly = new Polygon3(); 
    2169                                         backPoly = new Polygon3(); 
    2170  
    2171                                         candidatePolys[i]->Split(planes[j], *frontPoly,  
    2172                                                                                          *backPoly, splitPts); 
    2173                                         DEL_PTR(candidatePolys[i]); 
    2174  
    2175                                         if(sides[j] == true) 
    2176                                         { 
    2177                                                 candidatePolys[i] = frontPoly; 
    2178                                                 DEL_PTR(backPoly); 
    2179                                         } 
    2180                                         else 
    2181                                         { 
    2182                                                 candidatePolys[i] = backPoly; 
    2183                                                 DEL_PTR(frontPoly); 
    2184                                         } 
    2185                                          
    2186                                         break; 
    2187  
    2188                                 case Polygon3::BACK_SIDE: 
    2189                                         if (sides[j])  
    2190                                                 inside = false; 
    2191                                         break; 
    2192                                 case Polygon3::FRONT_SIDE: 
    2193                                         if (!sides[j]) 
    2194                                                 inside = false; 
    2195                                         break; 
    2196                                 case Polygon3::COINCIDENT: 
    2197                                         break; 
    2198                                 default: 
    2199                                         break; 
    2200                         } 
    2201                 } 
    2202                  
    2203                 if (inside) 
     2128                if (candidatePolys[i]) 
    22042129                        cell.push_back(candidatePolys[i]); 
    2205                 else 
    2206                         DEL_PTR(candidatePolys[i]); 
    2207         } 
    2208 } 
    2209  
    2210 void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const 
    2211 { 
    2212         vector<BspLeaf *> leaves = vc->mBspLeaves; 
    2213  
    2214         vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
    2215  
    2216         for (it = leaves.begin(); it != it_end; ++ it) 
    2217                 ConstructGeometry(*it, cell); 
    2218 } 
     2130        } 
     2131} 
     2132 
    22192133 
    22202134int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,  
     
    22292143                 
    22302144        // planes needed to verify that we found neighbor leaf. 
    2231         vector<Plane3> planes; 
    2232         vector<bool> sides; 
    2233  
    2234         ExtractSplitPlanes(n, planes, sides); 
     2145        vector<Plane3> halfSpaces; 
     2146        ExtractHalfSpaces(n, halfSpaces); 
    22352147 
    22362148        while (!nodeStack.empty())  
     
    22432155            if (node != n && (!onlyUnmailed || !node->Mailed())) 
    22442156                        { 
    2245                                 // test all planes of current node on neighbour 
     2157                                // test all planes of current node if candidate really 
     2158                                // is neighbour 
    22462159                                PolygonContainer neighborCandidate; 
    22472160                                ConstructGeometry(node, neighborCandidate); 
    22482161                                 
    22492162                                bool isAdjacent = true; 
    2250                                 for (int i = 0; (i < planes.size()) && isAdjacent; ++ i) 
     2163                                for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i) 
    22512164                                { 
    22522165                                        const int cf =  
    2253                                                 Polygon3::ClassifyPlane(neighborCandidate, planes[i]); 
    2254  
    2255                                         if ((cf == Polygon3::BACK_SIDE) && sides[i]) 
    2256                                                 isAdjacent = false; 
    2257                                         else if ((cf == Polygon3::FRONT_SIDE) && !sides[i]) 
     2166                                                Polygon3::ClassifyPlane(neighborCandidate, halfSpaces[i]); 
     2167 
     2168                                        if (cf == Polygon3::BACK_SIDE) 
    22582169                                                isAdjacent = false; 
    22592170                                } 
     
    24092320 *************************************************************/ 
    24102321 
    2411 BspNodeGeometry::BspNodeGeometry(const PolygonContainer &polys,  
    2412                                                                  const vector<Plane3> &planes,  
    2413                                                                  const vector<bool> &sides): 
    2414 mPolys(polys), mPlanes(planes), mSides(sides) 
    2415 {}                                          
    2416  
    2417 BspNodeGeometry::BspNodeGeometry(const vector<Plane3> &planes,  
    2418                                                                  const vector<bool> &sides): 
    2419 mPlanes(planes), mSides(sides) 
    2420 {} 
    2421  
    24222322BspNodeGeometry::~BspNodeGeometry() 
    24232323{ 
     
    24302330} 
    24312331 
    2432 void BspNodeGeometry::SplitGeometry(BspNodeGeometry frontChild. 
    2433                                                                         BspNodeGeometry backChild, 
     2332void BspNodeGeometry::SplitGeometry(BspNodeGeometry &front, 
     2333                                                                        BspNodeGeometry &back, 
    24342334                                                                        const BspTree &tree,                                              
    2435                                                                         const Plane3 &splitPlane, 
    2436                                                                         const bool side) const 
    2437 { 
    2438         //BspNodeGeometry *childCell = new BspNodeGeometry(mPlanes, mSides); 
    2439  
     2335                                                                        const Plane3 &splitPlane) const 
     2336{        
    24402337        // get cross section of new polygon 
    24412338        Polygon3 *planePoly = tree.GetBoundingBox().CrossSection(splitPlane); 
    24422339 
    2443         Polygon3 *frontPoly = NULL;//new Polygon3(planePoly->mVertices); 
    2444         Polygon3 *backPoly = NULL; //new Polygon3(planePoly->mVertices); 
    2445  
    2446         // polygon is split by all other planes 
    2447         for (int i = 0; (i < (int)mPlanes.size()) && planePoly; ++ i) 
    2448         { 
    2449                 const int cf = planePoly->ClassifyPlane(mPlanes[i]); 
    2450                          
    2451                 // split new polygon with all previous planes 
    2452                 switch (cf) 
    2453                 { 
    2454                         case Polygon3::SPLIT: 
    2455                                 { 
    2456                                         VertexContainer splitPts; 
    2457                                  
    2458                                         frontPoly = new Polygon3(); 
    2459                                         backPoly = new Polygon3(); 
    2460  
    2461                                         planePoly->Split(mPlanes[i], *frontPoly, *backPoly, splitPts); 
    2462                                         DEL_PTR(planePoly); 
    2463  
    2464                                         if(mSides[i] == true) 
    2465                                         { 
    2466                                                 planePoly = frontPoly; 
    2467                                                 DEL_PTR(backPoly); 
    2468                                         } 
    2469                                         else 
    2470                                         { 
    2471                                                 planePoly = backPoly; 
    2472                                                 DEL_PTR(frontPoly); 
    2473                                         } 
    2474                                          
    2475                                         if (!planePoly->Valid()) 
    2476                                                 DEL_PTR(planePoly); 
    2477                                 } 
    2478                                 break; 
    2479                         case Polygon3::BACK_SIDE: 
    2480                                 if (mSides[i])  
    2481                                         DEL_PTR(planePoly); 
    2482                                 break; 
    2483                         case Polygon3::FRONT_SIDE: 
    2484                                 if (!mSides[i]) 
    2485                                         DEL_PTR(planePoly); 
    2486                                 break; 
    2487                         case Polygon3::COINCIDENT: 
    2488                                 break; 
    2489                         default: 
    2490                                 break; 
    2491                 } 
    2492         } 
    2493          
     2340        planePoly = SplitPolygon(planePoly, tree); 
     2341 
    24942342        //-- plane poly splits all other cell polygons 
    24952343        for (int i = 0; i < (int)mPolys.size(); ++ i) 
     
    25132361                                        DEL_PTR(poly); 
    25142362 
    2515                                         if (side == true) 
    2516                                         { 
    2517                                                 poly = frontPoly; 
    2518                                                 DEL_PTR(backPoly); 
    2519                                         } 
    2520                                         else 
    2521                                         { 
    2522                                                 poly = backPoly; 
    2523                                                 DEL_PTR(frontPoly); 
    2524                                         } 
    2525                                         if (!poly->Valid()) 
    2526                                                 DEL_PTR(poly); 
    2527                                         else 
    2528                                                 childCell->mPolys.push_back(poly); 
     2363                                        if (frontPoly->Valid()) 
     2364                                                front.mPolys.push_back(frontPoly); 
     2365                                        if (backPoly->Valid()) 
     2366                                                back.mPolys.push_back(backPoly); 
    25292367                                } 
    25302368                                 
    25312369                                break; 
    25322370                        case Polygon3::BACK_SIDE: 
    2533                                 if (!side)  
    2534                                         childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices));                         
     2371                                back.mPolys.push_back(new Polygon3(mPolys[i]->mVertices));                       
    25352372                                break; 
    25362373                        case Polygon3::FRONT_SIDE: 
    2537                                 if (side) 
    2538                                         childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices));         
     2374                                front.mPolys.push_back(new Polygon3(mPolys[i]->mVertices));      
    25392375                                break; 
    25402376                        case Polygon3::COINCIDENT: 
    2541                                 childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices)); 
     2377                                //front.mPolys.push_back(CreateReversePolygon(mPolys[i])); 
     2378                                //back.mPolys.push_back(new Polygon3(mPolys[i]->mVertices)); 
    25422379                                break; 
    25432380                        default: 
     2381                                break; 
     2382                } 
     2383        } 
     2384 
     2385        //-- finally add the new polygon to the child cells 
     2386        if (planePoly) 
     2387        { 
     2388                // add polygon with normal pointing into positive half space to back cell 
     2389                back.mPolys.push_back(planePoly); 
     2390                // add polygon with reverse orientation to front cell 
     2391                front.mPolys.push_back(planePoly->CreateReversePolygon()); 
     2392        } 
     2393 
     2394        //Debug << "returning new geometry " << mPolys.size() << " CHILD: " << childCell->mPolys.size() << endl; 
     2395        //Debug << "old area " << this->GetArea() << " new: " << childCell->GetArea() << endl; 
     2396} 
     2397 
     2398Polygon3 *BspNodeGeometry::SplitPolygon(Polygon3 *planePoly, 
     2399                                                                                const BspTree &tree) const 
     2400{ 
     2401        // polygon is split by all other planes 
     2402        for (int i = 0; (i < (int)mPolys.size()) && planePoly; ++ i) 
     2403        { 
     2404                Plane3 plane = mPolys[i]->GetSupportingPlane(); 
     2405 
     2406                const int cf =  
     2407                        planePoly->ClassifyPlane(plane); 
     2408                         
     2409                // split new polygon with all previous planes 
     2410                switch (cf) 
     2411                { 
     2412                        case Polygon3::SPLIT: 
     2413                                { 
     2414                                        VertexContainer splitPts; 
    25442415                                 
     2416                                        Polygon3 *frontPoly = new Polygon3(); 
     2417                                        Polygon3 *backPoly = new Polygon3(); 
     2418 
     2419                                        planePoly->Split(plane, *frontPoly, *backPoly, splitPts); 
     2420                                        DEL_PTR(planePoly); 
     2421 
     2422                                        if (backPoly->Valid()) 
     2423                                                planePoly = backPoly; 
     2424                                        else 
     2425                                                DEL_PTR(backPoly); 
     2426                                } 
    25452427                                break; 
    2546                 } 
    2547         } 
    2548  
    2549         //-- finally add the new polygon 
    2550         if (planePoly) 
    2551         { 
    2552                 childCell->mPolys.push_back(planePoly); 
    2553                 childCell->mPlanes.push_back(splitPlane); 
    2554                 childCell->mSides.push_back(side); 
    2555         } 
    2556  
    2557         Debug << "returning new geometry " << mPolys.size() << " CHILD: " << childCell->mPolys.size() << endl; 
    2558  
    2559         Debug << "old area " << this->GetArea() << " new: " << childCell->GetArea() << endl; 
    2560         return childCell; 
    2561 } 
    2562  
    2563 /*void BspNodeGeometry::SplitPolygon(Polygon3 *poly, 
    2564                                                                    const BspTree &tree) const 
    2565 { 
    2566 }*/ 
     2428                        case Polygon3::FRONT_SIDE: 
     2429                                DEL_PTR(planePoly); 
     2430                break; 
     2431                        // polygon is taken as it is 
     2432                        case Polygon3::BACK_SIDE: 
     2433                        case Polygon3::COINCIDENT: 
     2434                        default: 
     2435                                break; 
     2436                } 
     2437        } 
     2438 
     2439        return planePoly; 
     2440} 
Note: See TracChangeset for help on using the changeset viewer.