VMotion.cpp
Engine/source/Verve/Torque3D/VMotion.cpp
Public Functions
Detailed Description
Public Functions
_attachPathObject(VPath * pPath, SceneObject * pObject, const bool & pForward, const bool & pRelative, const S32 & pStartNodeIndex, const S32 & pEndNodeIndex, const String & pOrientation, const String & pOrientationData)
getClientObject(NetObject * pObject)
1 2//----------------------------------------------------------------------------- 3// Verve 4// Copyright (C) 2014 - Violent Tulip 5// 6// Permission is hereby granted, free of charge, to any person obtaining a copy 7// of this software and associated documentation files (the "Software"), to 8// deal in the Software without restriction, including without limitation the 9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10// sell copies of the Software, and to permit persons to whom the Software is 11// furnished to do so, subject to the following conditions: 12// 13// The above copyright notice and this permission notice shall be included in 14// all copies or substantial portions of the Software. 15// 16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22// IN THE SOFTWARE. 23//----------------------------------------------------------------------------- 24#include "Verve/Torque/TMotion.h" 25#include "Verve/VPath/VPath.h" 26 27//----------------------------------------------------------------------------- 28 29// Sync the local connection when editing path objects? 30// Note: This was originally done so that editing was very smooth, but it turns 31// out that any lag was due to errors in the pathing operations 32// themselves. If issues persist, then uncomment this definition and you 33// might see a marked improvement in performance while editing in Verve. 34//#define VT_SYNC_LOCALCLIENT 35 36//----------------------------------------------------------------------------- 37// 38// Utility Methods. 39// 40//----------------------------------------------------------------------------- 41 42NetObject *getClientObject( NetObject *pObject ) 43{ 44 if ( !pObject ) 45 { 46 return NULL; 47 } 48 49 NetConnection *toServer = NetConnection::getConnectionToServer(); 50 NetConnection *toClient = NetConnection::getLocalClientConnection(); 51 if ( !toServer || !toClient ) 52 { 53 return NULL; 54 } 55 56 const S32 ghostIndex = toClient->getGhostIndex( pObject ); 57 if ( ghostIndex == -1 ) 58 { 59 return NULL; 60 } 61 62 return toServer->resolveGhost( ghostIndex ); 63} 64 65void _attachPathObject( VPath *pPath, SceneObject *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ) 66{ 67 if ( pOrientation == String::EmptyString ) 68 { 69 // Attach Object. 70 pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex ); 71 // Quit. 72 return; 73 } 74 75 // Fetch Orientation. 76 const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation ); 77 78 switch ( type ) 79 { 80 case VPathObject::k_OrientationFree : 81 case VPathObject::k_OrientationInterpolate : 82 case VPathObject::k_OrientationToPath : 83 { 84 // Attach Object. 85 pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, NULL ); 86 87 } break; 88 89 case VPathObject::k_OrientationToObject : 90 { 91 // Fetch Object. 92 SceneObject *lookAtObject = dynamic_cast<SceneObject*>( Sim::findObject( pOrientationData ) ); 93 // Valid Object? 94 if ( lookAtObject != NULL ) 95 { 96 // Attach Object. 97 pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtObject ); 98 } 99 100 } break; 101 102 case VPathObject::k_OrientationToPoint: 103 { 104 // Fetch Point. 105 Point3F lookAtPoint( 0.f, 0.f, 0.f ); 106 if ( dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ) == 3 ) 107 { 108 // Attach Object. 109 pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtPoint ); 110 } 111 112 } break; 113 } 114} 115 116//----------------------------------------------------------------------------- 117// 118// Path Methods. 119// 120//----------------------------------------------------------------------------- 121 122bool VTorque::isMovable( SimObject *pObject ) 123{ 124 return ( dynamic_cast<SceneObjectType*>( pObject ) != NULL ); 125} 126 127bool VTorque::isPath( SimObject *pObject ) 128{ 129 return ( dynamic_cast<PathObjectType*>( pObject ) != NULL ); 130} 131 132bool VTorque::isPathObjectAttached( PathObjectType *pPath, SceneObjectType *pObject ) 133{ 134 if ( !pPath || !pObject ) 135 { 136 // Sanity! 137 return false; 138 } 139 140 // Return. 141 return pPath->isObjectAttached( pObject ); 142} 143 144F32 VTorque::getPathNodeLength( PathObjectType *pPath, const S32 &pNode ) 145{ 146 if ( !pPath ) 147 { 148 // Sanity! 149 return false; 150 } 151 152 // Normalize Node Index. 153 S32 nodeIndex = pNode; 154 pPath->normalizeNodeIndex( nodeIndex ); 155 156 // Fetch Node. 157 VPathNode *node = pPath->getNode( nodeIndex ); 158 159 // Return Length. 160 return node->getLength(); 161} 162 163void VTorque::attachPathObject( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ) 164{ 165 if ( !pPath || !pObject ) 166 { 167 // Sanity! 168 return; 169 } 170 171 // Attach Object. 172 _attachPathObject( pPath, pObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData ); 173 174#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 175 176 // Fetch the client Path. 177 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 178 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 179 if ( clientPath && clientObject ) 180 { 181 // Attach Object. 182 _attachPathObject( clientPath, clientObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData ); 183 } 184 185#endif 186} 187 188void VTorque::detachPathObject( PathObjectType *pPath, SceneObjectType *pObject ) 189{ 190 if ( !pPath || !pObject ) 191 { 192 // Sanity! 193 return; 194 } 195 196 // Detach Object. 197 pPath->detachObject( pObject ); 198 199#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 200 201 // Fetch the client Path. 202 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 203 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 204 if ( clientPath && clientObject ) 205 { 206 // Detach Object. 207 clientPath->detachObject( clientObject ); 208 } 209 210#endif 211} 212 213void VTorque::setPathObjectActive( PathObjectType *pPath, SceneObjectType *pObject, const bool &pActive ) 214{ 215 if ( !pPath || !pObject ) 216 { 217 // Sanity! 218 return; 219 } 220 221 // Update Object State. 222 pPath->setPathObjectActive( pObject, pActive ); 223 224#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 225 226 // Fetch the client Path. 227 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 228 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 229 if ( clientPath && clientObject ) 230 { 231 // Update Object State. 232 clientPath->setPathObjectActive( clientObject, pActive ); 233 } 234 235#endif 236} 237 238void VTorque::setPathObjectInterp( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pInterp ) 239{ 240 if ( !pPath || !pObject ) 241 { 242 // Sanity! 243 return; 244 } 245 246 // Update Path Object Interp. 247 pPath->setPathObjectInterp( pObject, pInterp ); 248 249#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 250 251 // Fetch the client Path. 252 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 253 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 254 if ( clientPath && clientObject ) 255 { 256 // Apply the same action. 257 clientPath->setPathObjectInterp( clientObject, pInterp ); 258 } 259 260#endif 261} 262 263void VTorque::setPathObjectOffset( PathObjectType *pPath, SceneObjectType *pObject, const Point3F &pOffset ) 264{ 265 if ( !pPath || !pObject ) 266 { 267 // Sanity! 268 return; 269 } 270 271 // Update Path Object Offset. 272 pPath->setPathObjectOffset( pObject, pOffset ); 273 274#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 275 276 // Fetch the client Path. 277 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 278 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 279 if ( clientPath && clientObject ) 280 { 281 // Apply the same action. 282 clientPath->setPathObjectOffset( clientObject, pOffset ); 283 } 284 285#endif 286} 287 288void VTorque::setPathObjectSpeed( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pSpeed ) 289{ 290 if ( !pPath || !pObject ) 291 { 292 // Sanity! 293 return; 294 } 295 296 // Update Path Speed. 297 pPath->setPathObjectSpeed( pObject, pSpeed ); 298 299#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 300 301 // Fetch the client Path. 302 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 303 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 304 if ( clientPath && clientObject ) 305 { 306 // Apply the same action. 307 clientPath->setPathObjectSpeed( clientObject, pSpeed ); 308 } 309 310#endif 311} 312 313void VTorque::setPathObjectOrientation( PathObjectType *pPath, SceneObjectType *pObject, const String &pOrientation, const String &pOrientationData ) 314{ 315 if ( !pPath || !pObject ) 316 { 317 // Sanity! 318 return; 319 } 320 321 // Set the orientation mode. 322 // Note: Call the console method so we don't have to handle all the different modes here. 323 Con::executef( pPath, "setPathObjectOrientationMode", pObject->getIdString(), pOrientation, pOrientationData ); 324 325#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 326 327 // TODO: Handle synching the client path immediately. 328 329#endif 330 331 /* 332 // Set the Default Mode. 333 if ( pOrientation == String::EmptyString ) 334 { 335 // Apply Mode. 336 pPath->setPathObjectOrientationMode( pObject, VPathObject::k_OrientationToPath ); 337 return; 338 } 339 340 // Fetch Orientation. 341 const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation ); 342 343 switch ( type ) 344 { 345 case VPathObject::k_OrientationFree : 346 case VPathObject::k_OrientationInterpolate : 347 case VPathObject::k_OrientationToPath : 348 { 349 350 // Apply Mode. 351 pPath->setPathObjectOrientationMode( pObject, type ); 352 353 } break; 354 355 case VPathObject::k_OrientationToObject : 356 { 357 358 // Fetch Object. 359 SceneObjectType *lookAtObject; 360 if ( !Sim::findObject( pOrientationData, lookAtObject ) ) 361 { 362 // Invalid Object. 363 return; 364 } 365 366 // Apply Mode. 367 pPath->setPathObjectOrientationMode( pObject, type, lookAtObject ); 368 369 } break; 370 371 case VPathObject::k_OrientationToPoint: 372 { 373 374 // Fetch Point. 375 Point3F lookAtPoint( 0.f, 0.f, 0.f ); 376 dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); 377 378 // Apply Mode. 379 pPath->setPathObjectOrientationMode( pObject, type, lookAtPoint ); 380 381 } break; 382 } 383 */ 384} 385 386void VTorque::setPathObjectForward( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward ) 387{ 388 if ( !pPath || !pObject ) 389 { 390 // Sanity! 391 return; 392 } 393 394 // Update Path Object Forward. 395 pPath->setPathObjectForward( pObject, pForward ); 396 397#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 398 399 // Fetch the client Path. 400 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 401 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 402 if ( clientPath && clientObject ) 403 { 404 // Apply the same action. 405 clientPath->setPathObjectForward( clientObject, pForward ); 406 } 407 408#endif 409} 410 411void VTorque::setPathObjectNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ) 412{ 413 if ( !pPath || !pObject ) 414 { 415 // Sanity! 416 return; 417 } 418 419 // Update Object Current Node. 420 pPath->setPathObjectNode( pObject, pNode ); 421 422#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 423 424 // Fetch the client Path. 425 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 426 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 427 if ( clientPath && clientObject ) 428 { 429 // Update Object Current Node. 430 clientPath->setPathObjectNode( clientObject, pNode ); 431 } 432 433#endif 434} 435 436void VTorque::setPathObjectEndNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ) 437{ 438 if ( !pPath || !pObject ) 439 { 440 // Sanity! 441 return; 442 } 443 444 // Update Object End Node. 445 pPath->setPathObjectEndNode( pObject, pNode ); 446 447#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) 448 449 // Fetch the client Path. 450 VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) ); 451 SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) ); 452 if ( clientPath && clientObject ) 453 { 454 // Update Object End Node. 455 clientPath->setPathObjectEndNode( clientObject, pNode ); 456 } 457 458#endif 459} 460