Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgrePolygon.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 6.9 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Copyright (c) 2006 Matthias Fink, netAllied GmbH <matthias.fink@web.de>                                                         
9Also see acknowledgements in Readme.html
10
11This program is free software; you can redistribute it and/or modify it under
12the terms of the GNU Lesser General Public License as published by the Free Software
13Foundation; either version 2 of the License, or (at your option) any later
14version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19
20You should have received a copy of the GNU Lesser General Public License along with
21this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22Place - Suite 330, Boston, MA 02111-1307, USA, or go to
23http://www.gnu.org/copyleft/lesser.txt.
24
25You may alternatively use this source under the terms of a specific version of
26the OGRE Unrestricted License provided you have obtained such a license from
27Torus Knot Software Ltd.
28-----------------------------------------------------------------------------
29*/
30#include "OgreStableHeaders.h"
31#include "OgrePolygon.h"
32#include "OgreException.h"
33#include "OgreVector3.h"
34
35namespace Ogre
36{
37
38        //-----------------------------------------------------------------------
39        Polygon::Polygon()
40        : mNormal( Vector3::ZERO )
41        , mIsNormalSet(false)
42        {
43                // reserve space for 6 vertices to reduce allocation cost
44                mVertexList.reserve(6);
45        }
46        //-----------------------------------------------------------------------
47        Polygon::~Polygon()
48        {
49        }
50        //-----------------------------------------------------------------------
51        Polygon::Polygon( const Polygon& cpy )
52        {
53                mVertexList = cpy.mVertexList;
54                mNormal = cpy.mNormal;
55                mIsNormalSet = cpy.mIsNormalSet;
56        }
57        //-----------------------------------------------------------------------
58        void Polygon::insertVertex(const Vector3& vdata, size_t vertex )
59        {
60                // TODO: optional: check planarity
61                OgreAssert(vertex <= getVertexCount(), "Insert position out of range" );
62
63                VertexList::iterator it = mVertexList.begin();
64
65                std::advance(it, vertex);
66                mVertexList.insert(it, vdata);
67
68        }
69        //-----------------------------------------------------------------------
70        void Polygon::insertVertex(const Vector3& vdata)
71        {
72                mVertexList.push_back(vdata);
73        }
74        //-----------------------------------------------------------------------
75        const Vector3& Polygon::getVertex( size_t vertex ) const
76        {
77                OgreAssert(vertex < getVertexCount(), "Search position out of range");
78
79                return mVertexList[vertex];
80        }
81        //-----------------------------------------------------------------------
82        void Polygon::setVertex(const Vector3& vdata, size_t vertex )
83        {
84                // TODO: optional: check planarity
85                OgreAssert(vertex < getVertexCount(), "Search position out of range" );
86
87                // set new vertex
88                mVertexList[ vertex ] = vdata;
89        }
90        //-----------------------------------------------------------------------
91        void Polygon::removeDuplicates( void )
92        {
93                for ( size_t i = 0; i < getVertexCount(); ++i )
94                {
95                        const Vector3& a = getVertex( i );
96                        const Vector3& b = getVertex( (i + 1)%getVertexCount() );
97
98                        if (a.positionEquals(b))
99                        {
100                                deleteVertex(i);
101                                --i;
102                        }
103                }
104        }
105        //-----------------------------------------------------------------------
106        size_t Polygon::getVertexCount( void ) const
107        {
108                return mVertexList.size();
109        }
110        //-----------------------------------------------------------------------
111        const Vector3& Polygon::getNormal( void )
112        {
113                OgreAssert( getVertexCount() >= 3, "Insufficient vertex count!" );
114
115                updateNormal();
116
117                return mNormal;
118        }
119        //-----------------------------------------------------------------------
120        void Polygon::updateNormal( void )
121        {
122                OgreAssert( getVertexCount() >= 3, "Insufficient vertex count!" );
123
124                if (mIsNormalSet)
125                        return;
126
127                // vertex order is ccw
128                const Vector3& a = getVertex( 0 );
129                const Vector3& b = getVertex( 1 );
130                const Vector3& c = getVertex( 2 );
131
132                // used method: Newell
133                mNormal.x = 0.5f * ( (a.y - b.y) * (a.z + b.z) +
134                                                           (b.y - c.y) * (b.z + c.z) + 
135                                                           (c.y - a.y) * (c.z + a.z));
136
137                mNormal.y = 0.5f * ( (a.z - b.z) * (a.x + b.x) +
138                                                           (b.z - c.z) * (b.x + c.x) + 
139                                                           (c.z - a.z) * (c.x + a.x));
140
141                mNormal.z = 0.5f * ( (a.x - b.x) * (a.y + b.y) +
142                                                           (b.x - c.x) * (b.y + c.y) + 
143                                                           (c.x - a.x) * (c.y + a.y));
144
145                mNormal.normalise();
146
147                mIsNormalSet = true;
148
149        }
150        //-----------------------------------------------------------------------
151        void Polygon::deleteVertex( size_t vertex )
152        {
153                OgreAssert( vertex < getVertexCount(), "Search position out of range" );
154
155                VertexList::iterator it = mVertexList.begin();
156                std::advance(it, vertex);
157
158                mVertexList.erase( it );
159        }
160        //-----------------------------------------------------------------------
161        void Polygon::storeEdges( Polygon::EdgeMap *edgeMap ) const
162        {
163                OgreAssert( edgeMap != NULL, "EdgeMap ptr is NULL" );
164
165                size_t vertexCount = getVertexCount();
166
167                for ( size_t i = 0; i < vertexCount; ++i )
168                {
169                        edgeMap->insert( Edge( getVertex( i ), getVertex( ( i + 1 ) % vertexCount ) ) );
170                }
171        }
172        //-----------------------------------------------------------------------
173        void Polygon::reset( void )
174        {
175                // could use swap() to free memory here, but assume most may be reused so avoid realloc
176                mVertexList.clear();
177
178                mIsNormalSet = false;
179        }
180        //-----------------------------------------------------------------------
181        bool Polygon::operator == (const Polygon& rhs) const
182        {
183                if ( getVertexCount() != rhs.getVertexCount() )
184                        return false;
185
186                // Compare vertices. They may differ in its starting position.
187                // find start
188                size_t start;
189                bool foundStart = false;
190                for (size_t i = 0; i < getVertexCount(); ++i )
191                {       
192                        if (getVertex(0).positionEquals(rhs.getVertex(i)))
193                        {
194                                start = i;
195                                foundStart = true;
196                                break;
197                        }
198                }
199
200                if (!foundStart)
201                        return false;
202
203                for (size_t i = 0; i < getVertexCount(); ++i )
204                {
205                        const Vector3& vA = getVertex( i );
206                        const Vector3& vB = rhs.getVertex( ( i + start) % getVertexCount() );
207
208                        if (!vA.positionEquals(vB))
209                                return false;
210                }
211
212                return true;
213        }
214        //-----------------------------------------------------------------------
215        std::ostream& operator<< ( std::ostream& strm, const Polygon& poly )
216        {
217                strm << "NUM VERTICES: " << poly.getVertexCount() << std::endl;
218
219                for (size_t j = 0; j < poly.getVertexCount(); ++j )
220                {
221                        strm << "VERTEX " << j << ": " << poly.getVertex( j ) << std::endl;
222                }
223
224                return strm;
225        }
226        //-----------------------------------------------------------------------
227}
Note: See TracBrowser for help on using the repository browser.