afxPath3D.cpp
Engine/source/afx/util/afxPath3D.cpp
Detailed Description
1 2 3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 5// Copyright (C) 2015 Faust Logic, Inc. 6// 7// Permission is hereby granted, free of charge, to any person obtaining a copy 8// of this software and associated documentation files (the "Software"), to 9// deal in the Software without restriction, including without limitation the 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11// sell copies of the Software, and to permit persons to whom the Software is 12// furnished to do so, subject to the following conditions: 13// 14// The above copyright notice and this permission notice shall be included in 15// all copies or substantial portions of the Software. 16// 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23// IN THE SOFTWARE. 24// 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 26 27#include "afx/arcaneFX.h" 28 29#include "console/console.h" 30 31#include "afx/util/afxPath3D.h" 32 33afxPath3D::afxPath3D() : mStart_time(0), mNum_points(0), mLoop_type(LOOP_CONSTANT), mEnd_time(0.0f) 34{ 35} 36 37afxPath3D::~afxPath3D() 38{ 39} 40 41void afxPath3D::sortAll() 42{ 43 mCurve.sort(); 44 mCurve_parameters.sort(); 45} 46 47void afxPath3D::setStartTime( F32 time ) 48{ 49 mStart_time = time; 50} 51 52void afxPath3D::setLoopType( U32 loop_type ) 53{ 54 mLoop_type = loop_type; 55} 56 57//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 58 59F32 afxPath3D::getEndTime() 60{ 61 return mEnd_time; 62} 63 64int afxPath3D::getNumPoints() 65{ 66 return mNum_points; 67} 68 69Point3F afxPath3D::getPointPosition( int index ) 70{ 71 if (index < 0 || index >= mNum_points) 72 return Point3F(0.0f, 0.0f, 0.0f); 73 74 return mCurve.getPoint(index); 75} 76 77F32 afxPath3D::getPointTime( int index ) 78{ 79 if (index < 0 || index >= mNum_points) 80 return 0.0f; 81 82 return mCurve_parameters.getKeyTime(index); 83} 84 85F32 afxPath3D::getPointParameter( int index ) 86{ 87 if (index < 0 || index >= mNum_points) 88 return 0.0f; 89 90 return mCurve_parameters.getKeyValue(index); 91} 92 93Point2F afxPath3D::getParameterSegment( F32 time ) 94{ 95 return mCurve_parameters.getSegment(time); 96} 97 98void afxPath3D::setPointPosition( int index, Point3F &p ) 99{ 100 if (index < 0 || index >= mNum_points) 101 return; 102 103 mCurve.setPoint(index, p); 104} 105 106//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 107 108F32 afxPath3D::calcCurveTime( F32 time ) 109{ 110 if( time <= mStart_time ) 111 return 0.0f; 112 if( time <= mEnd_time ) 113 return time-mStart_time; 114 115 switch( mLoop_type ) 116 { 117 case LOOP_CYCLE : 118 { 119 return mFmod( time-mStart_time, mEnd_time-mStart_time ); 120 } 121 case LOOP_OSCILLATE : 122 { 123 F32 t1 = time- mStart_time; 124 F32 t2 = mEnd_time - mStart_time; 125 126 if( (int)(t1/t2) % 2 ) // odd segment 127 return t2 - mFmod( t1, t2 ); 128 else // even segment 129 return mFmod( t1, t2 ); 130 } 131 case LOOP_CONSTANT : 132 default: 133 return mEnd_time; 134 } 135} 136 137Point3F afxPath3D::evaluateAtTime( F32 time ) 138{ 139 F32 ctime = calcCurveTime( time ); 140 F32 param = mCurve_parameters.evaluate( ctime ); 141 return mCurve.evaluate(param); 142} 143 144Point3F afxPath3D::evaluateAtTime(F32 t0, F32 t1) 145{ 146 F32 ctime = calcCurveTime(t0); 147 F32 param = mCurve_parameters.evaluate( ctime ); 148 Point3F p0 = mCurve.evaluate(param); 149 150 ctime = calcCurveTime(t1); 151 param = mCurve_parameters.evaluate( ctime ); 152 Point3F p1 = mCurve.evaluate(param); 153 154 return p1-p0; 155} 156 157Point3F afxPath3D::evaluateTangentAtTime( F32 time ) 158{ 159 F32 ctime = calcCurveTime( time ); 160 F32 param = mCurve_parameters.evaluate( ctime ); 161 return mCurve.evaluateTangent(param); 162} 163 164Point3F afxPath3D::evaluateTangentAtPoint( int index ) 165{ 166 F32 param = mCurve_parameters.getKeyValue(index); 167 return mCurve.evaluateTangent(param); 168} 169 170//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 171 172void afxPath3D::buildPath( int num_points, Point3F curve_points[], F32 start_time, F32 end_time ) 173{ 174 mNum_points = num_points; 175 176 // Add points to path 177 F32 param_inc = 1.0f / (F32)(num_points - 1); 178 F32 param = 0.0f; 179 for( int i = 0; i < num_points; i++, param += param_inc ) 180 { 181 if( i == num_points-1 ) 182 param = 1.0f; 183 mCurve.addPoint( param, curve_points[i] ); 184 } 185 186 mCurve.computeTangents(); 187 188 initPathParametersNEW( curve_points, start_time, end_time ); 189 190 sortAll(); 191} 192 193void afxPath3D::buildPath( int num_points, Point3F curve_points[], F32 speed ) 194{ 195 mNum_points = num_points; 196 197 // Add points to path 198 F32 param_inc = 1.0f / (F32)(num_points - 1); 199 F32 param = 0.0f; 200 for( int i = 0; i < num_points; i++, param += param_inc ) 201 { 202 if( i == num_points-1 ) 203 param = 1.0f; 204 mCurve.addPoint( param, curve_points[i] ); 205 } 206 207 initPathParameters( curve_points, speed ); 208 209 sortAll(); 210} 211 212void afxPath3D::buildPath( int num_points, Point3F curve_points[], 213 F32 point_times[], F32 time_offset, F32 time_factor ) 214{ 215 mNum_points = num_points; 216 217 // Add points to path 218 F32 param_inc = 1.0f / (F32)(num_points - 1); 219 F32 param = 0.0f; 220 for( int i = 0; i < num_points; i++, param += param_inc ) 221 { 222 if( i == num_points-1 ) 223 param = 1.0f; 224 mCurve.addPoint( param, curve_points[i] ); 225 226 mCurve_parameters.addKey( (point_times[i]+time_offset)*time_factor, param ); 227 } 228 229 // Set end time 230 mEnd_time = (point_times[num_points-1]+time_offset)*time_factor; 231 232 sortAll(); 233} 234 235void afxPath3D::buildPath( int num_points, Point3F curve_points[], Point2F curve_params[] ) 236{ 237 mNum_points = num_points; 238 239 // Add points to path 240 F32 param_inc = 1.0f / (F32)(num_points - 1); 241 F32 param = 0.0f; 242 for( int i = 0; i < num_points; i++, param += param_inc ) 243 { 244 if( i == num_points-1 ) 245 param = 1.0f; 246 mCurve.addPoint( param, curve_points[i] ); 247 } 248 249 // 250 for (int i = 0; i < num_points; i++) 251 mCurve_parameters.addKey( curve_params[i] ); 252 253 // Set end time 254 mEnd_time = curve_params[num_points - 1].x; 255 256 sortAll(); 257} 258 259void afxPath3D::reBuildPath() 260{ 261 mCurve.computeTangents(); 262 sortAll(); 263} 264 265void afxPath3D::initPathParameters( Point3F curve_points[], F32 speed ) 266{ 267 // Compute the time for each point dependent on the speed of the character and the 268 // distance it must travel (approximately!) 269 int num_segments = mNum_points - 1; 270 F32 *point_distances = new F32[num_segments]; 271 for( int i = 0; i < num_segments; i++ ) 272 { 273 Point3F p1 = curve_points[i+1]; 274 Point3F p0 = curve_points[i]; 275 276 point_distances[i] = (p1-p0).len(); 277 } 278 279 F32 *times = new F32[num_segments]; 280 F32 last_time = 0;//start_time; 281 for( int i = 0; i < num_segments; i++ ) 282 { 283 times[i] = last_time + (point_distances[i] / speed); 284 last_time = times[i]; 285 } 286 287 mCurve_parameters.addKey( 0, 0.0f );//start_time, 0.0f ); 288 F32 param_inc = 1.0f / (F32)(mNum_points - 1); 289 F32 param = 0.0f + param_inc; 290 for( int i = 0; i < num_segments; i++, param += param_inc ) 291 mCurve_parameters.addKey( times[i], param ); 292 293 // Set end time 294 mEnd_time = times[num_segments-1]; 295 296 if (point_distances) 297 delete [] point_distances; 298 if (times) 299 delete [] times; 300} 301 302void afxPath3D::initPathParametersNEW( Point3F curve_points[], F32 start_time, F32 end_time ) 303{ 304 int num_segments = mNum_points - 1; 305 F32 *point_distances = new F32[num_segments]; 306 F32 total_distance = 0.0f; 307 for( int i = 0; i < num_segments; i++ ) 308 { 309 Point3F p1 = curve_points[i+1]; 310 Point3F p0 = curve_points[i]; 311 312 point_distances[i] = (p1-p0).len(); 313 total_distance += point_distances[i]; 314 } 315 316 F32 duration = end_time - start_time; 317 318 F32 time = 0.0f; //start_time; 319 mCurve_parameters.addKey( time, 0.0f ); 320 F32 param_inc = 1.0f / (F32)(mNum_points - 1); 321 F32 param = 0.0f + param_inc; 322 for( int i=0; i < num_segments; i++, param += param_inc ) 323 { 324 time += (point_distances[i]/total_distance) * duration; 325 mCurve_parameters.addKey( time, param ); 326 } 327 328 // Set end time ???? 329 //end_time = time; 330 mStart_time = start_time; 331 mEnd_time = end_time; 332 333 if (point_distances) 334 delete [] point_distances; 335} 336 337void afxPath3D::print() 338{ 339 // curve.print(); 340 mCurve_parameters.print(); 341} 342 343//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 344