123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- //-----------------------------------------------------------------------------
- // Verve
- // Copyright (C) 2014 - Violent Tulip
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "Verve/Torque/TMotion.h"
- #include "Verve/VPath/VPath.h"
- //-----------------------------------------------------------------------------
- // Sync the local connection when editing path objects?
- // Note: This was originally done so that editing was very smooth, but it turns
- // out that any lag was due to errors in the pathing operations
- // themselves. If issues persist, then uncomment this definition and you
- // might see a marked improvement in performance while editing in Verve.
- //#define VT_SYNC_LOCALCLIENT
- //-----------------------------------------------------------------------------
- //
- // Utility Methods.
- //
- //-----------------------------------------------------------------------------
- NetObject *getClientObject( NetObject *pObject )
- {
- if ( !pObject )
- {
- return NULL;
- }
- NetConnection *toServer = NetConnection::getConnectionToServer();
- NetConnection *toClient = NetConnection::getLocalClientConnection();
- if ( !toServer || !toClient )
- {
- return NULL;
- }
- const S32 ghostIndex = toClient->getGhostIndex( pObject );
- if ( ghostIndex == -1 )
- {
- return NULL;
- }
- return toServer->resolveGhost( ghostIndex );
- }
- void _attachPathObject( VPath *pPath, SceneObject *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData )
- {
- if ( pOrientation == String::EmptyString )
- {
- // Attach Object.
- pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex );
- // Quit.
- return;
- }
- // Fetch Orientation.
- const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation );
- switch ( type )
- {
- case VPathObject::k_OrientationFree :
- case VPathObject::k_OrientationInterpolate :
- case VPathObject::k_OrientationToPath :
- {
- // Attach Object.
- pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, NULL );
- } break;
- case VPathObject::k_OrientationToObject :
- {
- // Fetch Object.
- SceneObject *lookAtObject = dynamic_cast<SceneObject*>( Sim::findObject( pOrientationData ) );
- // Valid Object?
- if ( lookAtObject != NULL )
- {
- // Attach Object.
- pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtObject );
- }
- } break;
- case VPathObject::k_OrientationToPoint:
- {
- // Fetch Point.
- Point3F lookAtPoint( 0.f, 0.f, 0.f );
- if ( dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ) == 3 )
- {
- // Attach Object.
- pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtPoint );
- }
- } break;
- }
- }
- //-----------------------------------------------------------------------------
- //
- // Path Methods.
- //
- //-----------------------------------------------------------------------------
- bool VTorque::isMovable( SimObject *pObject )
- {
- return ( dynamic_cast<SceneObjectType*>( pObject ) != NULL );
- }
- bool VTorque::isPath( SimObject *pObject )
- {
- return ( dynamic_cast<PathObjectType*>( pObject ) != NULL );
- }
- bool VTorque::isPathObjectAttached( PathObjectType *pPath, SceneObjectType *pObject )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return false;
- }
- // Return.
- return pPath->isObjectAttached( pObject );
- }
- F32 VTorque::getPathNodeLength( PathObjectType *pPath, const S32 &pNode )
- {
- if ( !pPath )
- {
- // Sanity!
- return false;
- }
- // Normalize Node Index.
- S32 nodeIndex = pNode;
- pPath->normalizeNodeIndex( nodeIndex );
- // Fetch Node.
- VPathNode *node = pPath->getNode( nodeIndex );
- // Return Length.
- return node->getLength();
- }
- void VTorque::attachPathObject( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
-
- // Attach Object.
- _attachPathObject( pPath, pObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Attach Object.
- _attachPathObject( clientPath, clientObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData );
- }
- #endif
- }
- void VTorque::detachPathObject( PathObjectType *pPath, SceneObjectType *pObject )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Detach Object.
- pPath->detachObject( pObject );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Detach Object.
- clientPath->detachObject( clientObject );
- }
- #endif
- }
- void VTorque::setPathObjectActive( PathObjectType *pPath, SceneObjectType *pObject, const bool &pActive )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Update Object State.
- pPath->setPathObjectActive( pObject, pActive );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Update Object State.
- clientPath->setPathObjectActive( clientObject, pActive );
- }
- #endif
- }
- void VTorque::setPathObjectInterp( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pInterp )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Update Path Object Interp.
- pPath->setPathObjectInterp( pObject, pInterp );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Apply the same action.
- clientPath->setPathObjectInterp( clientObject, pInterp );
- }
- #endif
- }
- void VTorque::setPathObjectOffset( PathObjectType *pPath, SceneObjectType *pObject, const Point3F &pOffset )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Update Path Object Offset.
- pPath->setPathObjectOffset( pObject, pOffset );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Apply the same action.
- clientPath->setPathObjectOffset( clientObject, pOffset );
- }
- #endif
- }
- void VTorque::setPathObjectSpeed( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pSpeed )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Update Path Speed.
- pPath->setPathObjectSpeed( pObject, pSpeed );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Apply the same action.
- clientPath->setPathObjectSpeed( clientObject, pSpeed );
- }
- #endif
- }
- void VTorque::setPathObjectOrientation( PathObjectType *pPath, SceneObjectType *pObject, const String &pOrientation, const String &pOrientationData )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Set the orientation mode.
- // Note: Call the console method so we don't have to handle all the different modes here.
- Con::executef( pPath, "setPathObjectOrientationMode", pObject->getIdString(), pOrientation, pOrientationData );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // TODO: Handle synching the client path immediately.
- #endif
- /*
- // Set the Default Mode.
- if ( pOrientation == String::EmptyString )
- {
- // Apply Mode.
- pPath->setPathObjectOrientationMode( pObject, VPathObject::k_OrientationToPath );
- return;
- }
- // Fetch Orientation.
- const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation );
- switch ( type )
- {
- case VPathObject::k_OrientationFree :
- case VPathObject::k_OrientationInterpolate :
- case VPathObject::k_OrientationToPath :
- {
- // Apply Mode.
- pPath->setPathObjectOrientationMode( pObject, type );
- } break;
- case VPathObject::k_OrientationToObject :
- {
- // Fetch Object.
- SceneObjectType *lookAtObject;
- if ( !Sim::findObject( pOrientationData, lookAtObject ) )
- {
- // Invalid Object.
- return;
- }
- // Apply Mode.
- pPath->setPathObjectOrientationMode( pObject, type, lookAtObject );
- } break;
- case VPathObject::k_OrientationToPoint:
- {
- // Fetch Point.
- Point3F lookAtPoint( 0.f, 0.f, 0.f );
- dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z );
- // Apply Mode.
- pPath->setPathObjectOrientationMode( pObject, type, lookAtPoint );
- } break;
- }
- */
- }
- void VTorque::setPathObjectForward( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Update Path Object Forward.
- pPath->setPathObjectForward( pObject, pForward );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Apply the same action.
- clientPath->setPathObjectForward( clientObject, pForward );
- }
- #endif
- }
- void VTorque::setPathObjectNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Update Object Current Node.
- pPath->setPathObjectNode( pObject, pNode );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Update Object Current Node.
- clientPath->setPathObjectNode( clientObject, pNode );
- }
- #endif
- }
- void VTorque::setPathObjectEndNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode )
- {
- if ( !pPath || !pObject )
- {
- // Sanity!
- return;
- }
- // Update Object End Node.
- pPath->setPathObjectEndNode( pObject, pNode );
- #if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT )
- // Fetch the client Path.
- VPath *clientPath = dynamic_cast<VPath*>( getClientObject( pPath ) );
- SceneObjectType *clientObject = dynamic_cast<SceneObjectType*>( getClientObject( pObject ) );
- if ( clientPath && clientObject )
- {
- // Update Object End Node.
- clientPath->setPathObjectEndNode( clientObject, pNode );
- }
- #endif
- }
|