123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731 |
- //-----------------------------------------------------------------------------
- // 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 "VPathObject.h"
- #include "VPath.h"
- #include "core/stream/bitStream.h"
- #include "sim/netConnection.h"
- //-----------------------------------------------------------------------------
- static U32 gOrientationTypeBits = getBinLog2( getNextPow2( VPathObject::k_OrientationTypeSize ) );
- //-----------------------------------------------------------------------------
- VPathObject::VPathObject( void ) :
- mActive( false ),
- mLastTime( 0 ),
- mLastDelta( 0.f ),
- mObject( NULL ),
- mTimeInterp( 0.f ),
- mPathInterp( 0.f ),
- mPosition( 0.f, 0.f, 0.f ),
- mOffset( 0.f, 0.f, 0.f ),
- mOrientation( 0.f, 1.f, 0.f ),
- mForward( true ),
- mSpeed( 10.f ),
- mSourceNode( 0 ),
- mDestinationNode( 0 ),
- mStartNode( 0 ),
- mEndNode( 0 )
- {
- // Init.
- mOrientationMode.Type = k_OrientationToPath;
- mOrientationMode.Object = NULL;
- mOrientationMode.Point = Point3F::Zero;
- // Set the initial mask.
- mNetState.setMaskBits( k_StateInit );
- // Reset Time.
- resetTime();
- // Reset Delta.
- resetDelta();
- VECTOR_SET_ASSOCIATION( mNetState );
- }
- VPathObject::~VPathObject( void )
- {
- // Void.
- }
- //-----------------------------------------------------------------------------
- //
- // Network Methods.
- //
- //-----------------------------------------------------------------------------
- U32 VPathObject::packUpdate( NetConnection *pConnection, BitStream *pStream )
- {
- // Init Return Mask.
- U32 retMask = 0;
- // Fetch State.
- VNetStateInfo *state = getState( pConnection );
- // Write Active.
- pStream->writeFlag( mActive );
- // Send Object Update?
- if ( pStream->writeFlag( state->Mask & k_StateUpdateObject ) )
- {
- // Successful Send?
- bool success = false;
- // Valid Object?
- if ( !mObject )
- {
- // No Object.
- pStream->writeFlag( false );
- }
- else
- {
- // Write Ghost Index.
- const S32 ghostIndex = pConnection->getGhostIndex( mObject );
- if ( pStream->writeFlag( ghostIndex != -1 ) )
- {
- // Write Ghost Id.
- pStream->writeInt( ghostIndex, NetConnection::GhostIdBitSize );
- // Success!
- success = true;
- // Clear Update.
- state->Mask &= ~k_StateUpdateObject;
- }
- }
- if ( !success )
- {
- // Try Again Later.
- retMask |= VPath::ObjectUpdateMask;
- }
- }
- // Send Mount Update?
- if ( pStream->writeFlag( state->Mask & k_StateUpdateMount ) )
- {
- // Successful Send?
- bool success = false;
- // Valid Objects?
- if ( !mObject || !mObject->getObjectMount() || ( state->Mask & k_StateUpdateObject ) )
- {
- // No Object.
- pStream->writeFlag( false );
- }
- else
- {
- // Write Ghost Index.
- const S32 ghostIndex = pConnection->getGhostIndex( mObject->getObjectMount() );
- if ( pStream->writeFlag( ghostIndex != -1 ) )
- {
- // Write Ghost Id.
- pStream->writeInt( ghostIndex, NetConnection::GhostIdBitSize );
- // Write Mount Node.
- pStream->writeInt( mObject->getMountNode(), SceneObject::NumMountPointBits );
- // Success!
- success = true;
- // Clear Update.
- state->Mask &= ~k_StateUpdateMount;
- }
- }
- if ( !success )
- {
- // Try Again Later.
- retMask |= VPath::ObjectUpdateMask;
- }
- }
- // Send Position Update?
- if ( pStream->writeFlag( state->Mask & k_StateUpdatePosition ) )
- {
- // Write Position.
- pStream->write( mTimeInterp );
- pStream->write( mPathInterp );
- pStream->write( mPosition.x );
- pStream->write( mPosition.y );
- pStream->write( mPosition.z );
- pStream->write( mOrientation.x );
- pStream->write( mOrientation.y );
- pStream->write( mOrientation.z );
- pStream->writeInt( mSourceNode, VPath::gMaxNodeBits );
- pStream->writeInt( mDestinationNode, VPath::gMaxNodeBits );
- // Clear Update.
- state->Mask &= ~k_StateUpdatePosition;
- }
- // Send State Update?
- if ( pStream->writeFlag( state->Mask & k_StateUpdateState ) )
- {
- // Successful Send?
- bool success = true;
- // Write State.
- pStream->writeInt( mOrientationMode.Type, gOrientationTypeBits );
- switch ( mOrientationMode.Type )
- {
- case k_OrientationToObject :
- {
- // Write Ghost Index.
- const S32 ghostIndex = pConnection->getGhostIndex( mOrientationMode.Object );
- if ( pStream->writeFlag( ghostIndex != -1 ) )
- {
- pStream->writeInt( ghostIndex, NetConnection::GhostIdBitSize );
- }
- else
- {
- // Failed.
- success = false;
- }
- } break;
- case k_OrientationToPoint :
- {
- // Write Point.
- pStream->write( mOrientationMode.Point.x );
- pStream->write( mOrientationMode.Point.y );
- pStream->write( mOrientationMode.Point.z );
- } break;
- }
- pStream->writeFlag( mForward );
- pStream->write( mSpeed );
- // Write Offset.
- pStream->write( mOffset.x );
- pStream->write( mOffset.y );
- pStream->write( mOffset.z );
- pStream->writeInt( mStartNode, VPath::gMaxNodeBits );
- pStream->writeInt( mEndNode, VPath::gMaxNodeBits );
- if ( success )
- {
- // Clear Update.
- state->Mask &= ~k_StateUpdateState;
- }
- else
- {
- // Try Again Later.
- retMask |= VPath::ObjectUpdateMask;
- }
- }
- // Return Mask.
- return retMask;
- }
- void VPathObject::unpackUpdate( NetConnection *pConnection, BitStream *pStream )
- {
- // Read Active.
- setActive( pStream->readFlag() );
- // Update Object?
- if ( pStream->readFlag() )
- {
- if ( pStream->readFlag() )
- {
- // Read Ghost Index.
- const S32 ghostIndex = pStream->readInt( NetConnection::GhostIdBitSize );
- // Resolve Object.
- setObject( static_cast<SceneObject*>( pConnection->resolveGhost( ghostIndex ) ) );
- // Reset Delta.
- resetDelta();
- }
- else
- {
- // Clear Object.
- mObject = NULL;
- }
- }
- // Update Mount?
- if ( pStream->readFlag() )
- {
- if ( pStream->readFlag() )
- {
- // Read Ghost Index.
- const S32 ghostIndex = pStream->readInt( NetConnection::GhostIdBitSize );
- // Read Mount Node.
- const S32 nodeIndex = pStream->readInt( SceneObject::NumMountPointBits );
- // Resolve Object.
- SceneObject *mountObject = static_cast<SceneObject*>( pConnection->resolveGhost( ghostIndex ) );
- // Mount Object.
- mountObject->mountObject( mObject, nodeIndex );
- }
- else
- {
- // ... unmount?
- }
- }
- // Update Position?
- if ( pStream->readFlag() )
- {
- // Read Updates.
- pStream->read( &mTimeInterp );
- pStream->read( &mPathInterp );
- pStream->read( &mPosition.x );
- pStream->read( &mPosition.y );
- pStream->read( &mPosition.z );
- pStream->read( &mOrientation.x );
- pStream->read( &mOrientation.y );
- pStream->read( &mOrientation.z );
- mSourceNode = pStream->readInt( VPath::gMaxNodeBits );
- mDestinationNode = pStream->readInt( VPath::gMaxNodeBits );
- }
- // Update Heading?
- if ( pStream->readFlag() )
- {
- // Read Orientation Mode.
- mOrientationMode.Type = ( eOrientationType )pStream->readInt( gOrientationTypeBits );
- switch ( mOrientationMode.Type )
- {
- case VPathObject::k_OrientationToObject :
- {
- if ( pStream->readFlag() )
- {
- // Read Ghost Index.
- const S32 ghostIndex = pStream->readInt( NetConnection::GhostIdBitSize );
- // Resolve Object.
- mOrientationMode.Object = static_cast<SceneObject*>( pConnection->resolveGhost( ghostIndex ) );
- }
- } break;
- case VPathObject::k_OrientationToPoint :
- {
- // Read Point.
- pStream->read( &mOrientationMode.Point.x );
- pStream->read( &mOrientationMode.Point.y );
- pStream->read( &mOrientationMode.Point.z );
- } break;
- }
- // Read Updates.
- mForward = pStream->readFlag();
- pStream->read( &mSpeed );
- pStream->read( &mOffset.x );
- pStream->read( &mOffset.y );
- pStream->read( &mOffset.z );
- mStartNode = pStream->readInt( VPath::gMaxNodeBits );
- mEndNode = pStream->readInt( VPath::gMaxNodeBits );
- }
- }
- //-----------------------------------------------------------------------------
- //
- // Property Methods.
- //
- //-----------------------------------------------------------------------------
- Point3F VPathObject::getWorldPosition( void )
- {
- return ( mPosition + mOffset );
- }
- Point3F VPathObject::getRenderWorldPosition( const F32 &pDelta )
- {
- return ( getPositionDelta( pDelta ) + mOffset );
- }
- MatrixF VPathObject::getTransform( void )
- {
- MatrixF mat( true );
- switch ( mOrientationMode.Type )
- {
- case k_OrientationInterpolate :
- case k_OrientationToObject :
- case k_OrientationToPoint :
- case k_OrientationToPath :
- {
- // Y-Axis.
- VectorF yVec = mOrientation;
- yVec.normalize();
- // X-Axis.
- VectorF xVec = mCross( yVec, VPath::gBezierUp );
- xVec.normalize();
- // Z-Axis.
- VectorF zVec = mCross( xVec, yVec );
- zVec.normalize();
- // Setup Object Transform.
- mat.setColumn( 0, xVec );
- mat.setColumn( 1, yVec );
- mat.setColumn( 2, zVec );
- mat.setColumn( 3, getWorldPosition() );
- } break;
- case k_OrientationFree :
- {
- // Fetch Current Transform.
- mat = mObject->getTransform();
- mat.setPosition( getWorldPosition() );
- } break;
- }
- // Return.
- return mat;
- }
- MatrixF VPathObject::getRenderTransform( const F32 &pDelta )
- {
- MatrixF mat( true );
- switch ( mOrientationMode.Type )
- {
- case k_OrientationInterpolate :
- case k_OrientationToObject :
- case k_OrientationToPoint :
- case k_OrientationToPath :
- {
- // Y-Axis.
- VectorF yVec = getOrientationDelta( pDelta );
- yVec.normalize();
- // X-Axis.
- VectorF xVec = mCross( yVec, VPath::gBezierUp );
- xVec.normalize();
- // Z-Axis.
- VectorF zVec = mCross( xVec, yVec );
- zVec.normalize();
- // Setup Object Transform.
- mat.setColumn( 0, xVec );
- mat.setColumn( 1, yVec );
- mat.setColumn( 2, zVec );
- mat.setColumn( 3, getRenderWorldPosition( pDelta ) );
- } break;
- case k_OrientationFree :
- {
- // Fetch Current Transform.
- mat = mObject->getRenderTransform();
- mat.setPosition( getRenderWorldPosition( pDelta ) );
- } break;
- }
- // Return.
- return mat;
- }
- void VPathObject::setActive( const bool &pActive )
- {
- // Update?
- if ( pActive != mActive )
- {
- // Apply.
- mActive = pActive;
- // Flag Update.
- setMaskBits( k_StateUpdatePosition );
- }
- }
- void VPathObject::setObject( SceneObject *pObject )
- {
- // Update?
- if ( pObject != mObject )
- {
- // Apply.
- mObject = pObject;
- // Flag Update.
- setMaskBits( k_StateUpdateObject );
- }
- }
- void VPathObject::setTimeInterp( const F32 &pInterp )
- {
- // Update?
- if ( mTimeInterp != pInterp )
- {
- // Apply.
- mTimeInterp = pInterp;
- // Flag Update.
- setMaskBits( k_StateUpdatePosition );
- }
- }
- void VPathObject::setPathInterp( const F32 &pInterp )
- {
- // Update?
- if ( mPathInterp != pInterp )
- {
- // Apply.
- mPathInterp = pInterp;
- // Flag Update.
- setMaskBits( k_StateUpdatePosition );
- }
- }
- void VPathObject::setPosition( const Point3F &pPosition )
- {
- // Update?
- if ( mPosition != pPosition )
- {
- // Update.
- mPosition = pPosition;
- // Flag Update.
- setMaskBits( k_StateUpdatePosition );
- }
- }
- void VPathObject::setOffset( const Point3F &pOffset )
- {
- // Update?
- if ( mOffset != pOffset )
- {
- // Update.
- mOffset = pOffset;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- void VPathObject::setOrientation( const VectorF &pOrientation )
- {
- // Update?
- if ( mOrientation != pOrientation )
- {
- // Update.
- mOrientation = pOrientation;
- // Flag Update.
- setMaskBits( k_StateUpdatePosition );
- }
- }
- void VPathObject::setOrientationMode( const eOrientationType &pType )
- {
- // Update?
- if ( mOrientationMode.Type != pType )
- {
- // Update.
- mOrientationMode.Type = pType;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- void VPathObject::setOrientationMode( const eOrientationType &pType, SceneObject *pObject )
- {
- AssertFatal( ( pType == k_OrientationToObject ) && ( pObject != NULL ), "VPathObject::setOrientationMode() - Invalid mOrientation Type." );
- // Update?
- if ( ( mOrientationMode.Type != pType ) || ( mOrientationMode.Object != pObject ) )
- {
- // Update.
- mOrientationMode.Type = pType;
- mOrientationMode.Object = pObject;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- void VPathObject::setOrientationMode( const eOrientationType &pType, const Point3F &pPoint )
- {
- AssertFatal( pType == k_OrientationToPoint, "VPathObject::setOrientationMode() - Invalid mOrientation Type." );
- // Update?
- if ( ( mOrientationMode.Type != pType ) || ( mOrientationMode.Point != pPoint ) )
- {
- // Update.
- mOrientationMode.Type = pType;
- mOrientationMode.Point = pPoint;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- void VPathObject::setForward( const bool &pForward )
- {
- // Update?
- if ( mForward != pForward )
- {
- // Update.
- mForward = pForward;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- void VPathObject::setSpeed( const F32 &pSpeed )
- {
- // Update?
- if ( mSpeed != pSpeed )
- {
- // Update.
- mSpeed = pSpeed;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- void VPathObject::setNode( const S32 &pSourceNodeIndex, const S32 &pDestinationNodeIndex )
- {
- // Update?
- if ( ( mSourceNode != pSourceNodeIndex ) || ( mDestinationNode != pDestinationNodeIndex ) )
- {
- // Update.
- mSourceNode = pSourceNodeIndex;
- mDestinationNode = pDestinationNodeIndex;
- // Flag Update.
- setMaskBits( k_StateUpdatePosition );
- }
- }
- void VPathObject::setStartNode( const S32 &pNodeIndex )
- {
- // Update?
- if ( mStartNode != pNodeIndex )
- {
- // Update.
- mStartNode = pNodeIndex;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- void VPathObject::setEndNode( const S32 &pNodeIndex )
- {
- // Update?
- if ( mEndNode != pNodeIndex )
- {
- // Update.
- mEndNode = pNodeIndex;
- // Flag Update.
- setMaskBits( k_StateUpdateState );
- }
- }
- //-----------------------------------------------------------------------------
- //
- // Delta Methods.
- //
- //-----------------------------------------------------------------------------
- void VPathObject::resetDelta( void )
- {
- mDelta.Position[0] = mPosition;
- mDelta.Position[1] = mPosition;
- mDelta.Orientation[0] = mOrientation;
- mDelta.Orientation[1] = mOrientation;
- }
- void VPathObject::resetDelta( const Point3F &pPosition, const VectorF &pOrientation )
- {
- mDelta.Position[0] = pPosition;
- mDelta.Position[1] = pPosition;
- mDelta.Orientation[0] = pOrientation;
- mDelta.Orientation[1] = pOrientation;
- }
- void VPathObject::popDelta( void )
- {
- mDelta.Position[0] = mDelta.Position[1];
- mDelta.Orientation[0] = mDelta.Orientation[1];
- }
- void VPathObject::pushDelta( const Point3F &pPosition, const VectorF &pOrientation )
- {
- mDelta.Position[1] = pPosition;
- mDelta.Orientation[1] = pOrientation;
- }
- Point3F VPathObject::getPositionDelta( const F32 &pInterp )
- {
- Point3F interpPosition;
- interpPosition.interpolate( mDelta.Position[1], mDelta.Position[0], pInterp );
- return interpPosition;
- }
- VectorF VPathObject::getOrientationDelta( const F32 &pInterp )
- {
- VectorF interpOrientation;
- interpOrientation.interpolate( mDelta.Orientation[1], mDelta.Orientation[0], pInterp );
- interpOrientation.normalize();
- return interpOrientation;
- }
- //-----------------------------------------------------------------------------
- //
- // Enumeration Methods.
- //
- //-----------------------------------------------------------------------------
- // Implement the Orientation Type enum list.
- ImplementEnumType( VPathObjectOrientationType, "" )
- { VPathObject::k_OrientationFree, "FREE" },
- { VPathObject::k_OrientationInterpolate, "INTERPOLATE" },
- { VPathObject::k_OrientationToPath, "TOPATH" },
- { VPathObject::k_OrientationToObject, "TOOBJECT" },
- { VPathObject::k_OrientationToPoint, "TOPOINT" },
- EndImplementEnumType;
- VPathObject::eOrientationType VPathObject::getOrientationTypeEnum( const char *pLabel )
- {
- VPathObject::eOrientationType out;
- if ( !castConsoleTypeFromString( out, pLabel ) )
- {
- // Bah!
- return VPathObject::k_OrientationFree;
- }
- // Return.
- return out;
- }
- StringTableEntry VPathObject::getOrientationTypeLabel( const eOrientationType &pType )
- {
- // Return.
- return castConsoleTypeToString( pType );
- }
|