AreaEdge.cpp

Go to the documentation of this file.
00001 /*
00002 SagaEngine library
00003 Copyright (c) 2002-2006 Skalden Studio AS
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to distribute the library under the terms of the 
00010 Q Public License version 1.0. Be sure to read and understand the license
00011 before using the library. It should be included here, or you may read it
00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl
00013 
00014 The original version of this library can be located at:
00015 http://www.sagaengine.com/
00016 
00017 Rune Myrland
00018 rune@skalden.com
00019 */
00020 
00021 
00022 #include "AreaEdge.hpp"
00023 #include "CollisionComponent.hpp"
00024 #include "../schema/SimSchema.hpp"
00025 #include "../pos/Pos.hpp"
00026 
00027 
00028 namespace se_core {
00029 
00030     AreaEdge
00031     ::AreaEdge() : controlPointCount_(0) {
00032     }
00033 
00034 
00035     void AreaEdge
00036     ::addLink(const Point2& p1, const Point2& p2) {
00037         int index1 = _getOrAddControlPoint(p1);
00038         int index2 = _getOrAddControlPoint(p2);
00039         AssertFatal(links_[ index1 ] == -1, "The point " << p1 << " already links to another point");
00040 
00041         links_[ index1 ] = index2;
00042     }
00043 
00044 
00045     void AreaEdge
00046     ::removeLink(const Point2& p1, const Point2& p2) {
00047         int index1 = _getOrAddControlPoint(p1);
00048         int index2 = _getOrAddControlPoint(p2);
00049         AssertFatal(links_[ index1 ] == index2, "The point " << p1 << " doesn't link to another point");
00050 
00051         links_[ index1 ] = -1;
00052     }
00053 
00054     int AreaEdge
00055     ::_getOrAddControlPoint(const Point2& p) {
00056         // Find control point and return the index if it already exists.
00057         for(int i = 0; i < controlPointCount_; ++i) {
00058             if(controlPoints_[ i ].equals(p))
00059                 return i;
00060         }
00061         // Didn't exist, so add it and return the new index
00062         Assert(controlPointCount_ < MAX_CONTROL_POINTS);
00063         controlPoints_[ controlPointCount_ ] = p;
00064         links_[ controlPointCount_ ] = -1;
00065         return controlPointCount_++;
00066     }
00067 
00068 
00069     coor_t AreaEdge
00070     ::distance(const Point2& p, Point2& dest) const {
00071         Point2 tmp;
00072         coor_double_t nearest = 65536.0f * 65536.0f, d;
00073         for(int i = 0; i < controlPointCount_; ++i) {
00074             // Is there a link from this control point?
00075             if(links_[ i ] == -1) {
00076                 // No? Try next then.
00077                 continue;
00078             }
00079 
00080             // Calculate nearest point on this line
00081             tmp.nearestPoint(controlPoints_[i], controlPoints_[ links_[ i ] ], p);
00082 
00083             // Closer than nearest on other lines?
00084             if(nearest < 0 || (d = tmp.distanceSquared(p)) < nearest) {
00085                 nearest = d;
00086                 dest.set(tmp);
00087             }
00088         }
00089         return CoorT::sqrt(nearest);
00090     }
00091 
00092 
00093     bool AreaEdge
00094     ::isGuilty(const Point2& oldP, const Point2& nextP) const {
00095         Point2 tmp;
00096         int nearestIndex = -1;
00097         coor_double_t nearest = 65536.0f * 65536.0f, d;
00098         for(int i = 0; i < controlPointCount_; ++i) {
00099             // Is there a link from this control point?
00100             if(links_[ i ] == -1) {
00101                 // No? Try next then.
00102                 continue;
00103             }
00104 
00105             // Calculate nearest point on this line
00106             tmp.nearestPoint(controlPoints_[i], controlPoints_[ links_[ i ] ], nextP);
00107 
00108             // Closer than nearest on other lines?
00109             if(nearest < 0 || (d = tmp.distanceSquared(nextP)) < nearest) {
00110                 nearest = d;
00111                 nearestIndex = i;
00112             }
00113         }
00114 
00115         bool isOldLeft = oldP.isLeft(controlPoints_[nearestIndex], controlPoints_[ links_[ nearestIndex ] ]);
00116         bool isNextLeft = nextP.isLeft(controlPoints_[nearestIndex], controlPoints_[ links_[ nearestIndex ] ]);
00117 
00118         if(isOldLeft != isNextLeft) {
00119             return true;
00120         }
00121 
00122         // Calculate nearest point on this line
00123         tmp.nearestPoint(controlPoints_[nearestIndex], controlPoints_[ links_[ nearestIndex ] ], oldP);
00124         coor_double_t distSq = tmp.distanceSquared(oldP);
00125 
00126         return (nearest < distSq);
00127         //return CoorT::sqrt(nearest);
00128     }
00129 }
00130 
00131 

Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:11 2007 by Doxygen version 1.3.9.1.

SourceForge.net Logo