00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <base/WaypointPathRep>
00026
00027 #include <base/Serializer>
00028
00029 using base::WaypointPathRep;
00030
00031
00032
00033
00034 base::Point3 WaypointPathRep::position(Real s) const
00035 {
00036 if (flags & ConstPos)
00037 return points[0];
00038
00039 Int i=findIndex(s);
00040 if (equals(s,si[i]))
00041 return points[i];
00042
00043 Vector3 v( points[i+1] - points[i] );
00044 Real ts( si[i+1] - si[i] );
00045
00046 Real ds = s-si[i];
00047 Vector3 dv( (ds/ts)*v );
00048
00049 return points[i] + dv;
00050 }
00051
00052
00053 base::Orient WaypointPathRep::orientation(Real s) const
00054 {
00055 if (flags & ConstOrient)
00056 return orients[0];
00057
00058 Int i=findIndex(s);
00059 if (Math::equals(s,si[i]))
00060 return orients[i];
00061
00062
00063 Quat4 q1( orients[i].getQuat4() );
00064 Quat4 q2( orients[i+1].getQuat4() );
00065 Real ts( si[i+1] - si[i] );
00066
00067 Real ds = s-si[i];
00068 Quat4 q( Quat4::interpolate(q1,q2,ds/ts) );
00069
00070 return Orient(q);
00071 }
00072
00073
00074 Real WaypointPathRep::distinguishedValue(Int i) const
00075 {
00076 if ((flags & ConstPos) && (flags && ConstOrient)) {
00077 Math::bound<Int>(i,0,1);
00078 return (i==0)?0.0:1.0;
00079 }
00080
00081 Math::bound<Int>(i,0,si.size()-1);
00082 return si[i];
00083 }
00084
00085
00086 Int WaypointPathRep::numDistinguishedValues() const
00087 {
00088 if ((flags & ConstPos) && (flags && ConstOrient))
00089 return 2;
00090
00091 return si.size();
00092 }
00093
00094
00095
00096
00097 void WaypointPathRep::computeSis()
00098 {
00099 if (points.size() < 2) flags |= ConstPos;
00100 if (orients.size() < 2) flags |= ConstOrient;
00101
00102
00103 if (points.size() == 0) points.at(0) = Point3();
00104 if (orients.size() == 0) orients.at(0) = Orient();
00105
00106
00107 if (!(flags & ConstPos)) {
00108
00109
00110
00111 Real pathLength = 0;
00112 Int i=1;
00113 si.resize(points.size());
00114 si[0] = 0;
00115 while (i<points.size()) {
00116 pathLength += (points[i] - points[i-1]).length();
00117 si[i] = pathLength;
00118 i++;
00119 }
00120
00121 if (pathLength > 0)
00122 for(Int i=0; i<points.size(); i++)
00123 si[i] /= pathLength;
00124
00125 }
00126 else if (!(flags & ConstOrient)) {
00127
00128
00129 Real pathLength = 0;
00130 Int i=1;
00131 si.resize(orients.size());
00132 si[0]=0;
00133 while (i<orients.size()) {
00134
00135
00136
00137
00138 Quat4 from(orients[i-1].getQuat4());
00139 Quat4 to(orients[i].getQuat4());
00140 pathLength += Quat4::angleBetween(from,to);
00141 si[i] = pathLength;
00142 i++;
00143 }
00144
00145 if (pathLength > 0)
00146 for(Int i=0; i<orients.size(); i++)
00147 si[i] /= pathLength;
00148 }
00149
00150
00151
00152
00153 }
00154
00155
00156 Int WaypointPathRep::findIndex(Real s) const
00157 {
00158
00159 if ((si[0] <= s) && (s <= si[1])) return 0;
00160 if ((si[si.size()-2] <= s) && (s <= si[si.size()-1])) return si.size()-2;
00161
00162 if (si.size()>4) {
00163
00164 Int high, i, low;
00165 for(low=1, high=si.size()-1; high-low > 1;) {
00166 i = (high+low)/2;
00167 if (s <= si[i]) high=i; else low=i;
00168 }
00169 if ((si[i]<=s) && (s<=si[i+1])) return i; else return i-1;
00170 }
00171 else {
00172
00173 Int i;
00174 for(i=0; i<si.size(); i++)
00175 if (si[i] > s) break;
00176 return i-1;
00177 }
00178 }
00179
00180
00181
00182 void WaypointPathRep::translate(const Vector3& t)
00183 {
00184 for(Int i=0; i<points.size(); i++)
00185 points[i] += t;
00186 }
00187
00188
00189 void WaypointPathRep::rotate(const Quat4& r)
00190 {
00191 for(Int i=0; i<points.size(); i++) {
00192 r.rotatePoint(points[i]);
00193 Quat4 q(orients[i].getQuat4());
00194 orients[i] = r*q;
00195 }
00196 }
00197
00198
00199 void WaypointPathRep::transform(const Matrix4& m)
00200 {
00201 for(Int i=0; i<points.size(); i++) {
00202 Point4 p(points[i]);
00203 p = m*p;
00204 points[i] = Point3(p.x,p.y,p.z);
00205
00206 Quat4 r;
00207 r.setRotation(m);
00208 Quat4 q(orients[i].getQuat4());
00209 orients[i] = r*q;
00210 }
00211 }
00212
00213
00214 void WaypointPathRep::scalePosition(Real s)
00215 {
00216 for(Int i=0; i<points.size(); i++) {
00217 points[i] *= s;
00218 }
00219 }
00220
00221
00222 void WaypointPathRep::serialize(Serializer& s)
00223 {
00224 s(flags,"flags");
00225 s(points,"points");
00226 s(orients,"orients");
00227 s(si,"si");
00228 }