(Mostly) updated verve implementation.

This commit is contained in:
Areloch 2019-03-07 16:23:41 -06:00
parent 775ca57047
commit 87ee749801
538 changed files with 68727 additions and 49 deletions

View file

@ -0,0 +1,143 @@
//-----------------------------------------------------------------------------
// 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 "VNetState.h"
//-----------------------------------------------------------------------------
U32 VNetState::gInvalidMask = 0;
//-----------------------------------------------------------------------------
VNetState::VNetState() :
mMask( 0 )
{
}
VNetState::~VNetState( void )
{
for ( VNetState::iterator itr = begin(); itr != end(); itr++ )
{
// Fetch info.
VNetStateInfo *state = ( *itr );
// Delete State.
delete state;
}
// Clear.
clear();
}
//-----------------------------------------------------------------------------
//
// Connection Methods.
//
//-----------------------------------------------------------------------------
bool VNetState::isConnection( NetConnection *pConnection )
{
for ( VNetState::iterator itr = begin(); itr != end(); itr++ )
{
VNetStateInfo *state = ( *itr );
if ( state->Connection == pConnection )
{
// Valid.
return true;
}
}
// Invalid.
return false;
}
void VNetState::addConnection( NetConnection *pConnection )
{
// Init State.
VNetStateInfo *state = new VNetStateInfo( pConnection, mMask );
// Add.
push_back( state );
}
void VNetState::clearConnection( NetConnection *pConnection )
{
for ( VNetState::iterator itr = begin(); itr != end(); itr++ )
{
VNetStateInfo *state = ( *itr );
if ( state->Connection == pConnection )
{
// Delete.
delete state;
// Erase.
erase( itr );
// Quit.
return;
}
}
}
//-----------------------------------------------------------------------------
//
// Mask Methods.
//
//-----------------------------------------------------------------------------
VNetStateInfo *VNetState::getState( NetConnection *pConnection )
{
for ( VNetState::iterator itr = begin(); itr != end(); itr++ )
{
VNetStateInfo *state = ( *itr );
if ( state->Connection == pConnection )
{
return state;
}
}
return NULL;
}
void VNetState::setMaskBits( const U32 &pMask )
{
// Apply Mask.
mMask |= pMask;
for ( VNetState::iterator itr = begin(); itr != end(); itr++ )
{
// Fetch info.
VNetStateInfo *state = ( *itr );
// Apply Mask.
state->Mask |= pMask;
}
}
void VNetState::clearMaskBits( const U32 &pMask )
{
// Clear Mask.
mMask &= ~pMask;
for ( VNetState::iterator itr = begin(); itr != end(); itr++ )
{
// Fetch info.
VNetStateInfo *state = ( *itr );
// Clear Mask.
state->Mask &= ~pMask;
}
}

View file

@ -0,0 +1,84 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _VT_VNETSTATE_H_
#define _VT_VNETSTATE_H_
#ifndef _NETCONNECTION_H_
#include "sim/netConnection.h"
#endif
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
//-----------------------------------------------------------------------------
struct VNetStateInfo
{
SimObjectPtr<NetConnection> Connection;
U32 Mask;
VNetStateInfo( void ) :
Connection( NULL ),
Mask( 0 )
{
// Void.
};
VNetStateInfo( NetConnection *pConnection, U32 pMask )
{
Connection = pConnection;
Mask = pMask;
};
};
//-----------------------------------------------------------------------------
class VNetState : public Vector<VNetStateInfo*>
{
protected:
static U32 gInvalidMask;
U32 mMask;
public:
VNetState( void );
virtual ~VNetState( void );
// Connection Methods.
bool isConnection( NetConnection *pConnection );
void addConnection( NetConnection *pConnection );
void clearConnection( NetConnection *pConnection );
// Property Methods.
VNetStateInfo *getState( NetConnection *pConnection );
void setMaskBits( const U32 &pMask );
void clearMaskBits( const U32 &pMask );
};
#endif // _VT_VNETSTATE_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,271 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _VT_VPATH_H_
#define _VT_VPATH_H_
#ifndef _SCENEOBJECT_H_
#include "scene/sceneObject.h"
#endif
#ifndef _VT_PATHNODE_H_
#include "VPathNode.h"
#endif
#ifndef _VT_PATHOBJECT_H_
#include "VPathObject.h"
#endif
//-----------------------------------------------------------------------------
typedef Vector<VPathNode*> VPathNodeVector;
typedef VPathNodeVector::iterator VPathNodeIterator;
typedef Vector<VPathObject*> VPathObjectVector;
typedef VPathObjectVector::iterator VPathObjectIterator;
//-----------------------------------------------------------------------------
class VPath : public SceneObject
{
typedef SceneObject Parent;
friend class VPathEditor;
public:
// Static Members.
static SimObjectPtr<SimSet> gServerSet;
static U32 gMaxNodeTransmit;
static U32 gMaxNodeBits;
static U32 gMaxNodeCount;
static U32 gMaxObjectTransmit;
static U32 gMaxObjectBits;
static U32 gMaxObjectCount;
static Point3F gBezierAxis;
static Point3F gBezierUp;
enum eMaskBits
{
InitialUpdateMask = Parent::NextFreeMask << 0,
PathUpdateMask = Parent::NextFreeMask << 1,
NodeUpdateMask = Parent::NextFreeMask << 2,
ObjectUpdateMask = Parent::NextFreeMask << 3,
NextFreeMask = Parent::NextFreeMask << 4,
};
enum ePathType
{
k_PathLinear,
k_PathBezier,
k_PathInvalid,
k_PathTypeSize,
};
private:
U32 mPathType;
VPathNodeVector mNodeList;
VPathObjectVector mObjectList;
public:
VPath( void );
~VPath( void );
bool onAdd( void );
void onDeleteNotify( SimObject *pObject );
void onRemove( void );
static void initPersistFields( void );
static SimSet *getServerSet( void );
// Editor Methods.
bool collideBox( const Point3F &pStart, const Point3F &pEnd, RayInfo* pInfo );
// Update Methods.
F32 getUpdatePriority( CameraScopeQuery *pFocusObject, U32 pUpdateMask, S32 pUpdateSkips );
void updateContainer( void );
void updateNodeTransforms( void );
void setTransform( const MatrixF &pMatrix );
void setScale( const VectorF &pScale );
void setPathType( const ePathType &pType );
static bool setPathType( void *pObject, const char *pArray, const char *pData );
// Mounting Methods.
U32 getAvailableMountIndex( void );
bool isMountIndex( const U32 &pIndex );
void mountObject( SceneObject *pObject, S32 pIndex, const MatrixF &pTransform = MatrixF::Identity );
void unmountObject( SceneObject *pObject );
void getMountTransform( S32 pIndex, const MatrixF &pInTransform, MatrixF *pTransform );
void getRenderMountTransform( F32 pDelta, S32 pIndex, const MatrixF &pInTransform, MatrixF *pTransform );
VectorF getMountVelocity( const U32 &pIndex );
// Persistence Methods.
void readFields( void );
void writeFields( Stream &pStream, U32 pTabStop );
U32 packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream );
void unpackUpdate( NetConnection *pConnection, BitStream *pStream );
DECLARE_CONOBJECT( VPath );
public:
// Node Methods.
static VPathNode *createNode( void );
static void deleteNode( VPathNode *pNode );
void clear( void );
VPathNode *getNode( const S32 &pNodeIndex );
VPathNode *addNode( const Point3F &pPosition, const QuatF &pRotation, const F32 &pWeight, const S32 &pLocation = -1 );
VPathNode *addNode( VPathNode *pNode, const S32 &pLocation = -1 );
void deleteNode( const S32 &pNodeIndex );
void removeNode( const S32 &pNodeIndex );
S32 normalizeNodeIndex( S32 &pNodeIndex );
S32 normalizeNodeIndex( const S32 &pNodeIndex );
S32 normalizeNodeIndex( S32 &pNodeIndex, const S32 &pNodeCount );
// Object Methods.
bool isObjectAttached( SceneObject *pObject );
VPathObject *getPathObject( SceneObject *pObject );
void attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode );
void attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode, const VPathObject::eOrientationType &pOrientationMode );
void attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode, const VPathObject::eOrientationType &pOrientationMode, void *pOrientationData );
void attachObject( VPathObject *pPathObject );
void onAttachObject( VPathObject *pPathObject );
void detachObject( SceneObject *pObject );
void detachObject( VPathObject *pPathObject );
void onDetachObject( VPathObject *pPathObject );
void processTick( const Move *pMove );
void advanceObject( VPathObject *pPathObject, const F32 &pDelta );
void updatePosition( VPathObject *pPathObject );
void updateOrientation( VPathObject *pPathObject );
void updateOrientation( VPathObject *pPathObject, const Point3F &pPathOrientation );
// Path Methods.
void calculatePath( void );
Point3F getAdvancedPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pInterpDelta );
Point3F getPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward );
Point3F getPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward, F32 &pPathInterp );
VectorF getPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward );
//
// Linear Path Methods.
void calculateLinearPath( VPathNode *pNode, VPathNode *pNextNode );
Point3F getAdvancedLinearPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pInterpDelta );
Point3F getLinearPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pInterp, const bool &pForward, F32 &pPathInterp );
VectorF getLinearPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pInterp, const bool &pForward );
//
// Bezier Path Methods.
void calculateBezierPath( VPathNode *pNode, VPathNode *pNextNode );
Point3F getAdvancedBezierPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pInterpDelta );
Point3F getBezierPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pInterp, const bool &pForward, F32 &pPathInterp );
Point3F getBezierPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pInterp, const Point3F &pReferencePosition, const F32 &pTargetDistance, const bool &pForward, const bool &pRelativeToReference, F32 &pPathInterpDelta );
VectorF getBezierPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pInterp, const bool &pForward );
public:
// Node Property Methods.
S32 getNodeCount( void );
Point3F getNodeLocalPosition( const S32 &pNodeIndex );
Point3F getNodeWorldPosition( const S32 &pNodeIndex );
QuatF getNodeLocalRotation( const S32 &pNodeIndex );
QuatF getNodeWorldRotation( const S32 &pNodeIndex );
F32 getNodeWeight( const S32 &pNodeIndex );
F32 getNodeLength( const S32 &pNodeIndex );
void setNodePosition( const S32 &pNodeIndex, const Point3F &pPosition );
void setNodeRotation( const S32 &pNodeIndex, const QuatF &pRotation );
void setNodeWeight( const S32 &pNodeIndex, const F32 &pWeight );
void setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType );
void setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType, const Point3F pPoint );
// Path Object Property Methods.
void setPathObjectActive( SceneObject *pObject, const bool &pActive );
void setPathObjectInterp( SceneObject *pObject, const F32 &pTimeInterp );
void setPathObjectOffset( SceneObject *pObject, const Point3F &pOffset );
void setPathObjectSpeed( SceneObject *pObject, const F32 &pSpeed );
void setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType );
void setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType, SceneObject *pLookAtObject );
void setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType, const Point3F pPoint );
void setPathObjectForward( SceneObject *pObject, const bool &pForward );
void setPathObjectNode( SceneObject *pObject, const S32 &pNodeIndex );
void setPathObjectEndNode( SceneObject *pObject, const S32 &pNodeIndex );
void setPathObjectInterp( VPathObject *pPathObject, const F32 &pTimeInterp );
};
//-----------------------------------------------------------------------------
// Define Types.
typedef VPath::ePathType VPathType;
// Declare Enum Types.
DefineEnumType( VPathType );
//-----------------------------------------------------------------------------
#endif // _VT_VPATH_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,293 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _VT_VPATHEDITOR_H_
#define _VT_VPATHEDITOR_H_
#ifndef _EDITTSCTRL_H_
#include "gui/worldEditor/editTSCtrl.h"
#endif
#ifndef _VT_VPATH_H_
#include "VPath.h"
#endif
#ifndef _UNDO_H_
#include "util/undo.h"
#endif
//-----------------------------------------------------------------------------
class VPathEditor : public EditTSCtrl
{
typedef EditTSCtrl Parent;
public:
enum RenderType
{
k_RenderSegments,
k_RenderNodes,
};
enum EditMode
{
k_Gizmo,
k_AddNode,
k_DeleteNode
};
struct Selection
{
Selection( void ) :
Path( NULL ),
Node( -1 )
{
TangentHandle[0].zero();
TangentHandle[1].zero();
};
VPath *Path;
S32 Node;
Point3F TangentHandle[2];
};
struct PathEditAction
{
PathEditAction( void ) :
Dirty( false ),
Transform( true )
{
// Void.
};
bool Dirty;
MatrixF Transform;
};
struct NodeEditAction
{
NodeEditAction( void ) :
Dirty( false ),
Position( 0.f, 0.f, 0.f ),
Rotation( 0.f, 0.f, 0.f, 0.f ),
Weight( 0.f )
{
// Void.
};
bool Dirty;
Point3F Position;
QuatF Rotation;
F32 Weight;
};
bool mIsDirty;
EditMode mEditMode;
Selection mSelection;
PathEditAction mPathEdit;
NodeEditAction mNodeEdit;
bool mEditWeight;
S32 mEditWeightHandle;
GFXStateBlockRef mStateBlock;
public:
VPathEditor( void );
virtual bool onAdd( void );
virtual bool onWake( void );
static void initPersistFields( void );
// Gui Events.
virtual void on3DMouseDown( const Gui3DMouseEvent &pEvent );
virtual void on3DMouseUp( const Gui3DMouseEvent &pEvent );
virtual void on3DMouseMove( const Gui3DMouseEvent &pEvent );
virtual void on3DMouseDragged( const Gui3DMouseEvent &pEvent );
// Render Methods.
virtual void setStateBlock( void );
virtual void renderScene( const RectI &pUpdateRect );
void renderPaths( const RenderType &pRenderType );
void renderPath( const RenderType &pRenderType, VPath *pPath, const ColorI &pColor );
void renderLinearPath( VPath *pPath, const ColorI &pColor );
void renderBezierPath( VPath *pPath, const ColorI &pColor );
DECLARE_CONOBJECT( VPathEditor );
public:
// Reference Methods.
VPath *getClientPath( VPath *pPath );
// Selection Methods.
inline bool isValidSelection( void ) { return ( mSelection.Path != NULL && mSelection.Node != -1 ); };
bool updateSelection( const Gui3DMouseEvent &pEvent );
void updateSelection( VPath *pPathObject, const S32 &pNodeIndex );
void updateSelection( void );
// Weight Editing.
bool isEditingWeight( const Gui3DMouseEvent &pEvent );
inline bool isEditingWeight( void ) { return mEditWeight; };
void updateWeight( const Gui3DMouseEvent &pEvent );
// Path Editor.
bool getPointOnPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform );
bool getPointOnLinearPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform );
bool getPointOnBezierPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform );
void setPathPosition( const Point3F &pPosition );
void setPathRotation( const QuatF &pRotation );
void setPathTransform( const MatrixF &pTransform );
void setPathScale( const VectorF &pScale );
// Node Editing.
void addNode( const Gui3DMouseEvent &pEvent );
void deleteNode( const S32 &pNodeIndex );
void setNodePosition( const S32 &pNodeIndex, const Point3F &pPosition );
void setNodeRotation( const S32 &pNodeIndex, const QuatF &pRotation );
void setNodeWeight( const S32 &pNodeIndex, const F32 &pWeight );
void setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType );
void setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType, const Point3F &pPoint );
void pushPathEdit( void );
void popPathEdit( void );
void pushNodeEdit( void );
void popNodeEdit( void );
void setWorldEditorDirty( void );
private:
class VPathEditorEditPathAction : public UndoAction
{
public:
VPathEditorEditPathAction( const UTF8 *pName = "" ) :
UndoAction( pName )
{
// Void.
};
VPathEditor *mEditor;
VPath *mPath;
MatrixF mTransform;
virtual void undo( void );
virtual void redo( void );
};
class VPathEditorEditNodeAction : public UndoAction
{
public:
VPathEditorEditNodeAction( const UTF8 *pName = "" ) :
UndoAction( pName )
{
// Void.
};
VPathEditor *mEditor;
VPath *mPath;
S32 mNodeIndex;
Point3F mNodePosition;
QuatF mNodeRotation;
F32 mNodeWeight;
VPathNode::sOrientation mNodeOrientation;
virtual void undo( void );
virtual void redo( void );
};
class VPathEditorAddNodeAction : public VPathEditorEditNodeAction
{
public:
VPathEditorAddNodeAction( const UTF8 *pName = "" ) :
VPathEditorEditNodeAction( "Add Node" )
{
// Void.
};
virtual void undo( void );
virtual void redo( void );
};
class VPathEditorDeleteNodeAction : public VPathEditorEditNodeAction
{
public:
VPathEditorDeleteNodeAction( const UTF8 *pName = "" ) :
VPathEditorEditNodeAction( "Delete Node" )
{
// Void.
};
virtual void undo( void );
virtual void redo( void );
};
};
//-----------------------------------------------------------------------------
// Define Types.
typedef VPathEditor::EditMode VPathEditorMode;
// Declare Enum Types.
DefineEnumType( VPathEditorMode );
//-----------------------------------------------------------------------------
namespace Utility
{
bool FindNearestDistanceBetweenLines( const Point3F &pA0, const Point3F &pA1, const Point3F &pB0, const Point3F &pB1, Point3F *pOutA, Point3F *pOutB, F32 *pDist );
bool IntersectLineSegment( const Point3F &pA0, const Point3F &pA1, const Point3F &pB0, const Point3F &pB1, const bool pSnap, Point3F *pX );
bool FindNearestPointOnLine( const Point3F &pSrcPosition, const Point3F &pA0, const Point3F &pA1, Point3F *pDstPosition );
F32 GetPitch( const VectorF &pVec );
F32 GetYaw( const VectorF &pVec );
};
//-----------------------------------------------------------------------------
#endif // _VT_VPATHEDITOR_H_

View file

@ -0,0 +1,470 @@
//-----------------------------------------------------------------------------
// 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 "VPathNode.h"
#include "VPath.h"
#include "core/stream/bitStream.h"
#include "core/strings/stringUnit.h"
#include "sim/netConnection.h"
//-----------------------------------------------------------------------------
static U32 gOrientationTypeBits = getBinLog2( getNextPow2( VPathNode::k_OrientationTypeSize ) );
//-----------------------------------------------------------------------------
VPathNode::VPathNode( void ) :
mPath( NULL ),
mLocalPosition( Point3F( 0.f, 0.f, 0.f ) ),
mLocalRotation( QuatF( 0.f, 0.f, 0.f, 1.f ) ),
mWorldPosition( Point3F( 0.f, 0.f, 0.f ) ),
mWorldRotation( QuatF( 0.f, 0.f, 0.f, 1.f ) ),
mWeight( 10.f ),
mLength( 0.f )
{
// Init.
mOrientationMode.Type = k_OrientationFree;
mOrientationMode.Point = Point3F::Zero;
// Set the initial mask.
mNetState.setMaskBits( k_StateInit );
VECTOR_SET_ASSOCIATION( mNetState );
}
VPathNode::~VPathNode( void )
{
mNetState.clear();
}
//-----------------------------------------------------------------------------
//
// Network Methods.
//
//-----------------------------------------------------------------------------
U32 VPathNode::packNode( NetConnection *pConnection, BitStream *pStream )
{
// Init Return Mask.
U32 retMask = 0;
// Fetch State.
VNetStateInfo *state = getState( pConnection );
// Note: This is out of sync with VPathNode::unpackUpdate().
// If you're ever going to use these methods outside of VPath, you
// will need to read a flag *before* calling unpack!
// Was the Node Created?
if ( pStream->writeFlag( state->Mask & k_StateCreate ) )
{
// Clear Update.
state->Mask &= ~k_StateCreate;
}
// Send mLocalPosition?
if ( pStream->writeFlag( state->Mask & k_StateUpdatePosition ) )
{
// Write mLocalPosition.
pStream->write( mLocalPosition.x );
pStream->write( mLocalPosition.y );
pStream->write( mLocalPosition.z );
// Clear Update.
state->Mask &= ~k_StateUpdatePosition;
}
// Send mLocalRotation?
if ( pStream->writeFlag( state->Mask & k_StateUpdateRotation ) )
{
// Write mLocalRotation.
pStream->write( mLocalRotation.x );
pStream->write( mLocalRotation.y );
pStream->write( mLocalRotation.z );
pStream->write( mLocalRotation.w );
// Clear Update.
state->Mask &= ~k_StateUpdateRotation;
}
// Send mWeight?
if ( pStream->writeFlag( state->Mask & k_StateUpdateWeight ) )
{
// Write mWeight.
pStream->write( mWeight );
// Clear Update.
state->Mask &= ~k_StateUpdateWeight;
}
// Send Orientation Update?
if ( pStream->writeFlag( state->Mask & k_StateUpdateOrientation ) )
{
// Clear Update?
bool clearUpdate = true;
// Write State.
pStream->writeInt( mOrientationMode.Type, gOrientationTypeBits );
switch ( mOrientationMode.Type )
{
case k_OrientationToPoint :
{
// Write Point.
pStream->write( mOrientationMode.Point.x );
pStream->write( mOrientationMode.Point.y );
pStream->write( mOrientationMode.Point.z );
} break;
}
if ( clearUpdate )
{
// Clear Update.
state->Mask &= ~k_StateUpdateOrientation;
}
}
// Return Mask.
return retMask;
}
void VPathNode::unpackNode( NetConnection *pConnection, BitStream *pStream )
{
// Note: This is out of sync with VPathNode::packUpdate().
// If you're ever going to use these methods outside of VPath, you
// will need to read a flag *before* calling unpack!
// Update World Data.
bool updateWorld = false;
// Update Local Position?
if ( pStream->readFlag() )
{
// Read Local Position.
pStream->read( &mLocalPosition.x );
pStream->read( &mLocalPosition.y );
pStream->read( &mLocalPosition.z );
updateWorld = true;
}
// Update Local Rotation?
if ( pStream->readFlag() )
{
// Read Local Rotation.
pStream->read( &mLocalRotation.x );
pStream->read( &mLocalRotation.y );
pStream->read( &mLocalRotation.z );
pStream->read( &mLocalRotation.w );
updateWorld = true;
}
// Update Weight?
if ( pStream->readFlag() )
{
// Read Weight.
pStream->read( &mWeight );
}
// Update Orientation?
if ( pStream->readFlag() )
{
// Read Orientation Mode.
mOrientationMode.Type = ( eOrientationType )pStream->readInt( gOrientationTypeBits );
switch ( mOrientationMode.Type )
{
case k_OrientationToPoint :
{
// Read Point.
pStream->read( &mOrientationMode.Point.x );
pStream->read( &mOrientationMode.Point.y );
pStream->read( &mOrientationMode.Point.z );
} break;
}
}
if ( updateWorld )
{
// Update World Position.
updateWorldData();
}
}
String VPathNode::toString( void )
{
String retBuffer;
// Buffer Node Properties.
// {Position} {Rotation} {Weight}
const AngAxisF aa( mLocalRotation );
retBuffer = String::ToString( "%f %f %f %f %f %f %f %f", mLocalPosition.x, mLocalPosition.y, mLocalPosition.z,
aa.axis.x, aa.axis.y, aa.axis.z, aa.angle,
mWeight );
// Add Tab.
retBuffer += "\t";
// Determine the Type.
StringTableEntry typeString = getOrientationTypeLabel( mOrientationMode.Type );
switch( mOrientationMode.Type )
{
case k_OrientationFree :
{
// Buffer String.
retBuffer += typeString;
} break;
case k_OrientationToPoint:
{
// Fetch Point.
const Point3F &lookAtPoint = mOrientationMode.Point;
// Buffer String.
retBuffer += String::ToString( "%s %f %f %f", typeString, lookAtPoint.x, lookAtPoint.y, lookAtPoint.z );
} break;
}
// Return String.
return retBuffer;
}
bool VPathNode::fromString( const String &pString )
{
// Split Data.
// {Position} {Rotation} {Weight}
const char *baseData = StringUnit::getUnit( pString.c_str(), 0, "\t" );
Point3F pos;
AngAxisF aa;
F32 weight;
// Scan Base.
dSscanf( baseData, "%g %g %g %g %g %g %g %g", &pos.x, &pos.y, &pos.z,
&aa.axis.x, &aa.axis.y, &aa.axis.z, &aa.angle,
&weight );
// Apply Changes.
setLocalPosition( pos );
setLocalRotation( QuatF( aa ) );
setWeight( weight );
// Fetch Orientation Data.
String orientationData = StringUnit::getUnit( pString.c_str(), 1, "\t" );
// Fetch Orientation Type.
String orientationTypeString = orientationData;
if ( orientationData.find( " " ) )
{
// Use First Word.
orientationTypeString = orientationData.substr( 0, orientationData.find( " " ) );
}
// Set Orientation Type.
const eOrientationType &orientationType = getOrientationTypeEnum( orientationTypeString.c_str() );
switch( orientationType )
{
case k_OrientationFree :
{
// Apply Mode.
setOrientationMode( orientationType );
} break;
case k_OrientationToPoint:
{
// Fetch Point.
Point3F lookAtPoint;
// Buffer String.
dSscanf( orientationData.c_str(), "%*s %f %f %f", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z );
// Apply Mode.
setOrientationMode( orientationType, lookAtPoint );
} break;
}
return true;
}
//-----------------------------------------------------------------------------
//
// Property Methods.
//
//-----------------------------------------------------------------------------
Point3F VPathNode::getWorldPosition( void ) const
{
return mWorldPosition;
}
QuatF VPathNode::getWorldRotation( void ) const
{
return mWorldRotation;
}
MatrixF VPathNode::getWorldTransform( void ) const
{
MatrixF mat;
getWorldRotation().setMatrix( &mat );
mat.setPosition( getWorldPosition() );
return mat;
}
void VPathNode::setLocalPosition( const Point3F &pPosition )
{
// Update?
if ( mLocalPosition != pPosition )
{
// Apply.
mLocalPosition = pPosition;
// Update World Position.
updateWorldData();
// Flag Update.
setMaskBits( k_StateUpdatePosition );
}
}
void VPathNode::setLocalRotation( const QuatF &pRotation )
{
// Update?
if ( mLocalRotation != pRotation )
{
// Apply.
mLocalRotation = pRotation;
// Update World Rotation.
updateWorldData();
// Flag Update.
setMaskBits( k_StateUpdateRotation );
}
}
void VPathNode::setWeight( const F32 &pWeight )
{
// Update?
if ( mWeight != pWeight )
{
// Apply.
mWeight = pWeight;
// Flag Update.
setMaskBits( k_StateUpdateWeight );
}
}
void VPathNode::setOrientationMode( const eOrientationType &pType )
{
// Update?
if ( mOrientationMode.Type != pType )
{
// Update.
mOrientationMode.Type = pType;
// Flag Update.
setMaskBits( k_StateUpdateOrientation );
}
}
void VPathNode::setOrientationMode( const eOrientationType &pType, const Point3F &pPoint )
{
AssertFatal( pType == k_OrientationToPoint, "VPathNode::setOrientationMode() - Invalid mOrientation Type." );
// Update?
if ( ( mOrientationMode.Type != pType ) || ( mOrientationMode.Point != pPoint ) )
{
// Update.
mOrientationMode.Type = pType;
mOrientationMode.Point = pPoint;
// Flag Update.
setMaskBits( k_StateUpdateOrientation );
}
}
void VPathNode::updateWorldData( void )
{
if ( !mPath )
{
setWorldPosition( getLocalPosition() );
setWorldRotation( getLocalRotation() );
return;
}
// Fetch Path Details.
const MatrixF &pathTransform = mPath->getTransform();
const QuatF &pathRotation( pathTransform );
// Calculate the World Position.
Point3F newPosition = getLocalPosition();
newPosition.convolve( mPath->getScale() );
pathTransform.mulP( newPosition );
// Calculate the new Rotation.
QuatF newRotation;
newRotation.mul( getLocalRotation(), pathRotation );
// Apply.
setWorldPosition( newPosition );
setWorldRotation( newRotation );
}
//-----------------------------------------------------------------------------
//
// Enumeration Methods.
//
//-----------------------------------------------------------------------------
// Implement the Orientation Type enum list.
ImplementEnumType( VPathNodeOrientationType,"" )
{ VPathNode::k_OrientationFree, "FREE" },
{ VPathNode::k_OrientationToPoint, "TOPOINT" },
EndImplementEnumType;
VPathNode::eOrientationType VPathNode::getOrientationTypeEnum( const char *pLabel )
{
VPathNode::eOrientationType out;
if ( !castConsoleTypeFromString( out, pLabel ) )
{
// Bah!
return VPathNode::k_OrientationFree;
}
// Return.
return out;
}
StringTableEntry VPathNode::getOrientationTypeLabel( const eOrientationType &pType )
{
// Return.
return castConsoleTypeToString( pType );
}

View file

@ -0,0 +1,172 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _VT_VPATHNODE_H_
#define _VT_VPATHNODE_H_
#ifndef _GAMEBASE_H_
#include "T3D/gameBase/gameBase.h"
#endif
#ifndef _VNETSTATE_H_
#include "VNetState.h"
#endif
//-----------------------------------------------------------------------------
class VPath;
class VPathNode
{
public:
enum eState
{
k_StateUpdatePosition = BIT( 0 ),
k_StateUpdateRotation = BIT( 1 ),
k_StateUpdateWeight = BIT( 2 ),
k_StateUpdateOrientation = BIT( 3 ),
k_StateCreate = BIT( 4 ),
k_StateDelete = BIT( 5 ),
k_StateUpdate = ( k_StateUpdatePosition | k_StateUpdateRotation | k_StateUpdateWeight | k_StateUpdateOrientation ),
k_StateInit = ( k_StateCreate | k_StateUpdate ),
};
enum eOrientationType
{
k_OrientationFree,
k_OrientationToPoint,
k_OrientationTypeSize,
};
struct sOrientation
{
eOrientationType Type;
// k_OrientationToPoint
Point3F Point;
};
protected:
VPath *mPath;
VNetState mNetState;
sOrientation mOrientationMode;
Point3F mLocalPosition;
QuatF mLocalRotation;
Point3F mWorldPosition;
QuatF mWorldRotation;
F32 mWeight;
F32 mLength;
public:
VPathNode( void );
virtual ~VPathNode( void );
// Serialisation Methods.
virtual U32 packNode( NetConnection *pConnection, BitStream *pStream );
virtual void unpackNode( NetConnection *pConnection, BitStream *pStream );
virtual String toString( void );
virtual bool fromString( const String &pString );
//-------------------------------------------------------------------------
//
// Gets
//
//-------------------------------------------------------------------------
inline VPath *getPath( void ) const { return mPath; };
inline const Point3F &getLocalPosition( void ) const { return mLocalPosition; };
inline const QuatF &getLocalRotation( void ) const { return mLocalRotation; };
virtual Point3F getWorldPosition( void ) const;
virtual QuatF getWorldRotation( void ) const;
virtual MatrixF getWorldTransform( void ) const;
inline const F32 &getWeight( void ) const { return mWeight; };
inline const F32 &getLength( void ) const { return mLength; };
inline const sOrientation &getOrientationMode( void ) const { return mOrientationMode; };
//-------------------------------------------------------------------------
//
// Sets
//
//-------------------------------------------------------------------------
inline void setPath( VPath *pPath ) { mPath = pPath; };
void setLocalPosition( const Point3F &pPosition );
void setLocalRotation( const QuatF &pRotation );
inline void setWorldPosition( const Point3F &pPosition ) { mWorldPosition = pPosition; };
inline void setWorldRotation( const QuatF &pRotation ) { mWorldRotation = pRotation; };
void setWeight( const F32 &pWeight );
inline void setLength( const F32 &pLength ) { mLength = pLength; };
void setOrientationMode( const eOrientationType &pType );
void setOrientationMode( const eOrientationType &pType, const Point3F &pPoint );
void updateWorldData( void );
// Net State Methods.
inline VNetStateInfo *getState( NetConnection *pConnection ) { return mNetState.getState( pConnection ); };
inline void setMaskBits( const U32 &pMask ) { mNetState.setMaskBits( pMask ); };
inline void clearMaskBits( const U32 &pMask ) { mNetState.clearMaskBits( pMask ); };
inline bool isConnection( NetConnection *pConnection ) { return mNetState.isConnection( pConnection ); };
inline void addConnection( NetConnection *pConnection ) { mNetState.addConnection( pConnection ); };
inline void clearConnection( NetConnection *pConnection ) { mNetState.clearConnection( pConnection ); };
// Enum Methods.
static eOrientationType getOrientationTypeEnum( const char *pLabel );
static StringTableEntry getOrientationTypeLabel( const eOrientationType &pType );
};
//-----------------------------------------------------------------------------
// Define Types.
typedef VPathNode::eOrientationType VPathNodeOrientationType;
// Declare Enum Types.
DefineEnumType( VPathNodeOrientationType );
//-----------------------------------------------------------------------------
#endif // _VT_VPATHNODE_H_

View file

@ -0,0 +1,731 @@
//-----------------------------------------------------------------------------
// 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 );
}

View file

@ -0,0 +1,246 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _VT_VPATHOBJECT_H_
#define _VT_VPATHOBJECT_H_
#ifndef _GAMEBASE_H_
#include "T3D/gameBase/gameBase.h"
#endif
#ifndef _VNETSTATE_H_
#include "VNetState.h"
#endif
#ifndef _MOVEMANAGER_H_
#include "T3D/gameBase/moveManager.h"
#endif
//-----------------------------------------------------------------------------
class VPath;
class NetConnection;
struct VPathObject
{
public:
enum eState
{
k_StateUpdateObject = BIT( 0 ),
k_StateUpdateMount = BIT( 1 ),
k_StateUpdatePosition = BIT( 2 ),
k_StateUpdateState = BIT( 3 ),
k_StateAttach = BIT( 4 ),
k_StateDetach = BIT( 5 ),
k_StateUpdate = ( k_StateUpdateObject | k_StateUpdateMount | k_StateUpdatePosition | k_StateUpdateState ),
k_StateInit = ( k_StateAttach | k_StateUpdate ),
};
enum eOrientationType
{
k_OrientationFree,
k_OrientationInterpolate,
k_OrientationToPath,
k_OrientationToObject,
k_OrientationToPoint,
k_OrientationTypeSize,
};
struct sOrientation
{
eOrientationType Type;
// k_OrientationToObject
SceneObject *Object;
// k_OrientationToPoint
Point3F Point;
};
struct sDelta
{
Point3F Position[2];
VectorF Orientation[2];
};
protected:
bool mActive;
U32 mLastTime;
F32 mLastDelta;
SceneObject *mObject;
VNetState mNetState;
sDelta mDelta;
F32 mTimeInterp;
F32 mPathInterp;
Point3F mPosition;
Point3F mOffset;
sOrientation mOrientationMode;
VectorF mOrientation;
bool mForward;
F32 mSpeed;
S32 mSourceNode;
S32 mDestinationNode;
S32 mStartNode;
S32 mEndNode;
public:
VPathObject( void );
~VPathObject( void );
// Network Methods.
U32 packUpdate( NetConnection *pConnection, BitStream *pStream );
void unpackUpdate( NetConnection *pConnection, BitStream *pStream );
//-------------------------------------------------------------------------
//
// Gets
//
//-------------------------------------------------------------------------
inline const bool &isActive( void ) { return mActive; };
inline SceneObject *getObject( void ) { return mObject; };
inline const F32 &getTimeInterp( void ) { return mTimeInterp; };
inline const F32 &getPathInterp( void ) { return mPathInterp; };
inline const Point3F &getPosition( void ) { return mPosition; };
inline const Point3F &getOffset( void ) { return mOffset; };
inline const VectorF &getOrientation( void ) { return mOrientation; };
inline const sOrientation &getOrientationMode( void ) { return mOrientationMode; };
inline const bool &isForward( void ) { return mForward; };
inline const F32 &getSpeed( void ) { return mSpeed; };
inline const S32 &getSourceNode( void ) { return mSourceNode; };
inline const S32 &getDestinationNode( void ) { return mDestinationNode; };
inline const S32 &getStartNode( void ) { return mStartNode; };
inline const S32 &getEndNode( void ) { return mEndNode; };
Point3F getWorldPosition( void );
Point3F getRenderWorldPosition( const F32 &pDelta );
MatrixF getTransform( void );
MatrixF getRenderTransform( const F32 &pDelta );
inline F32 getTimeDelta( const bool &pUpdate = true )
{
if ( !pUpdate )
{
return mLastDelta;
}
// Calculate Delta.
const S32 time = Sim::getCurrentTime();
const F32 delta = ( time - mLastTime ) / 1000.f;
// Store Time.
mLastTime = time;
mLastDelta = delta;
// Return Delta.
return delta;
};
inline void resetTime( void )
{
mLastTime = Sim::getCurrentTime();
};
//-------------------------------------------------------------------------
//
// Sets
//
//-------------------------------------------------------------------------
void setActive( const bool &pActive );
void setObject( SceneObject *pObject );
void setTimeInterp( const F32 &pInterp );
void setPathInterp( const F32 &pInterp );
void setPosition( const Point3F &pPosition );
void setOffset( const Point3F &pOffset );
void setOrientation( const VectorF &pOrientation );
void setOrientationMode( const eOrientationType &pType );
void setOrientationMode( const eOrientationType &pType, SceneObject *pObject );
void setOrientationMode( const eOrientationType &pType, const Point3F &pPoint );
void setForward( const bool &pForward );
void setSpeed( const F32 &pSpeed );
void setNode( const S32 &pSourceNodeIndex, const S32 &pDestinationNodeIndex );
void setStartNode( const S32 &pNodeIndex );
void setEndNode( const S32 &pNodeIndex );
// Delta Methods.
void resetDelta( void );
void resetDelta( const Point3F &pPosition, const VectorF &pOrientation );
void popDelta( void );
void pushDelta( const Point3F &pPosition, const VectorF &pOrientation );
Point3F getPositionDelta( const F32 &pInterp );
VectorF getOrientationDelta( const F32 &pInterp );
// Net State Methods.
inline VNetStateInfo *getState( NetConnection *pConnection ) { return mNetState.getState( pConnection ); };
inline void setMaskBits( const U32 &pMask ) { mNetState.setMaskBits( pMask ); };
inline void clearMaskBits( const U32 &pMask ) { mNetState.clearMaskBits( pMask ); };
inline bool isConnection( NetConnection *pConnection ) { return mNetState.isConnection( pConnection ); };
inline void addConnection( NetConnection *pConnection ) { mNetState.addConnection( pConnection ); };
inline void clearConnection( NetConnection *pConnection ) { mNetState.clearConnection( pConnection ); };
// Enum Methods.
static eOrientationType getOrientationTypeEnum( const char *pLabel );
static StringTableEntry getOrientationTypeLabel( const eOrientationType &pType );
};
//-----------------------------------------------------------------------------
// Define Types.
typedef VPathObject::eOrientationType VPathObjectOrientationType;
// Declare Enum Types.
DefineEnumType( VPathObjectOrientationType );
//-----------------------------------------------------------------------------
#endif // _VT_VPATHOBJECT_H_