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.