source: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp @ 268

Revision 268, 3.5 KB checked in by mattausch, 19 years ago (diff)

did bsp stuff

Line 
1#include "Polygon3.h"
2#include "Mesh.h"
3#include "ViewCellBsp.h" // TODO: erase this
4// tolerance value for side relation
5#define SIDE_TOLERANCE 0.002f // TODO: Test different values
6
7Polygon3::Polygon3(): mMaterial(NULL)
8{}
9
10Polygon3::Polygon3(const VertexContainer &vertices): mVertices(vertices), mMaterial(NULL)
11{}
12
13Polygon3::Polygon3(Face *face, Mesh *parent)
14{       
15        VertexIndexContainer::iterator it = face->mVertexIndices.begin();
16        for (; it != face->mVertexIndices.end();  ++it)
17        {
18                mVertices.push_back(parent->mVertices[*it]);
19                mMaterial = parent->mMaterial;
20               
21                //Debug << parent->mVertices[*it] << endl;
22        }
23}
24
25Plane3 Polygon3::GetSupportingPlane() const
26{
27        Vector3 v1 = mVertices[0] - mVertices[1];
28        Vector3 v2 = mVertices[2] - mVertices[1];
29#ifdef _DEBUG
30        Debug << "plane spanned by " <<  v1 << ", " << v2  << endl;
31#endif
32        return Plane3(mVertices[0], mVertices[1], mVertices[2]);
33}
34
35void Polygon3::Split(Plane3 *partition, Polygon3 *front, Polygon3 *back, int &splits)
36{
37        splits = 0;
38        Vector3 ptA = mVertices[mVertices.size() - 1];
39       
40        int sideA = partition->Side(ptA, SIDE_TOLERANCE);
41       
42        VertexContainer::const_iterator it;
43
44        // find line - plane intersections
45        for (it = mVertices.begin(); it != mVertices.end(); ++ it)
46        {
47                Vector3 ptB = (*it);
48                int sideB = partition->Side(ptB, SIDE_TOLERANCE);
49       
50                // vertices on different sides => split
51            if (sideB > 0)
52                {
53                        if (sideA < 0)
54                        {
55                                //-- plane - line intersection
56                                Vector3 splitPt = partition->FindIntersection(ptA, ptB);
57                       
58                                // add vertex to both polygons
59                                front->mVertices.push_back(splitPt);
60                                back->mVertices.push_back(splitPt);
61                       
62                                ++ splits;
63                        }
64                        front->mVertices.push_back(ptB);
65                }
66                else if (sideB < 0)
67                {
68                        if (sideA > 0)
69                        {
70                                //-- plane - line intersection
71                                Vector3 splitPt = partition->FindIntersection(ptA, ptB);
72                       
73                                // add vertex to both polygons
74                                front->mVertices.push_back(splitPt);
75                                back->mVertices.push_back(splitPt);
76
77                                ++ splits;
78                        }
79                        back->mVertices.push_back(ptB);
80                }
81                else
82                {
83                        // vertex on plane => add vertex to both polygons
84                        front->mVertices.push_back(ptB);
85                        back->mVertices.push_back(ptB);
86                }
87       
88                ptA = ptB;
89                sideA = sideB;
90        }
91}
92
93int Polygon3::Side(const Plane3 &plane) const
94{
95        int classification = ClassifyPlane(plane);
96       
97        if (classification == BACK_SIDE)
98                return -1;
99        else if (classification == FRONT_SIDE)
100                return 1;
101
102        return 0;
103}
104
105int Polygon3::ClassifyPlane(const Plane3 &plane) const
106{
107        VertexContainer::const_iterator it;
108
109        bool onFrontSide = false;
110        bool onBackSide = false;
111
112        int count = 0;
113        // find possible line-plane intersections
114        for (it = mVertices.begin(); it != mVertices.end(); ++ it)
115        {
116                int side = plane.Side(*it, SIDE_TOLERANCE);
117                if (BspTree::displayDebug) Debug << "side: " << side << " " << plane.Distance(*it) << endl;
118
119                if (side > 0)
120                        onFrontSide = true;
121                else if (side < 0)
122                        onBackSide = true;
123               
124                //TODO: check if split goes through vertex
125                if (onFrontSide && onBackSide) // split
126                {
127                        return SPLIT;
128                }
129                // 3 vertices enough to decide coincident
130                else if (((++ count) >= 3) && !onFrontSide && !onBackSide)
131                        return COINCIDENT;
132        }
133
134        if (onBackSide)
135        {
136                return BACK_SIDE;
137        }
138        else if (onFrontSide)
139        {
140                return FRONT_SIDE;
141        }
142
143        // plane and polygon are coincident
144        return COINCIDENT;
145}
146
147
148Vector3
149Polygon3::Center() const
150{
151        int i;
152        Vector3 sum = mVertices[0];
153        for (i=1; i < mVertices.size(); i++)
154                sum += mVertices[i];
155       
156        return sum/i;
157}
158
159
160void
161Polygon3::Scale(const float scale)
162{
163        int i;
164        Vector3 center = Center();
165        for (i=0; i < mVertices.size(); i++) {
166                mVertices[i] = center + scale*(mVertices[i] - center);
167        }
168}
Note: See TracBrowser for help on using the repository browser.