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

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