(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,212 @@
//-----------------------------------------------------------------------------
// 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/Core/VController.h"
#include "Verve/Core/VGroup.h"
#include "Verve/Extension/Motion/VMotionEvent.h"
#include "Verve/Extension/Motion/VMotionTrack.h"
#include "console/consoleTypes.h"
#include "math/mMathFn.h"
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT( VMotionEvent );
//-----------------------------------------------------------------------------
VMotionEvent::VMotionEvent( void )
{
setLabel( "MotionEvent" );
}
//-----------------------------------------------------------------------------
//
// Callback Methods.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// VMotionEvent::onTrigger( pDelta, pDelta );
//
// The path object is told to move to the next node. If this event corresponds
// to Node 0, the object will move to Node 1. If the object reaches the node
// before the next event is triggered, then the object will stop moving.
//
// The object's position is only reset when the track is reset and not when an
// event is triggered.
//
//-----------------------------------------------------------------------------
void VMotionEvent::onTrigger( const S32 &pTime, const S32 &pDelta )
{
Parent::onTrigger( pTime, pDelta );
// Fetch Parent Track.
VMotionTrack *track;
if ( !getTrack( track ) )
{
// Invalid Track.
return;
}
// Fetch Path & Reference Object.
VTorque::PathObjectType *path = track->getPath();
VTorque::SceneObjectType *object = getSceneObject();
if ( !path || !object )
{
// Invalid.
return;
}
// Valid Destination Node?
if ( !isControllerLooping() && !getNextEvent() )
{
// Clear Active.
VTorque::setPathObjectActive( path, object, false );
// Quit.
return;
}
// Set Active.
VTorque::setPathObjectActive( path, object, true );
// Apply Speed.
VTorque::setPathObjectSpeed( path, object, getObjectSpeed() );
}
//-----------------------------------------------------------------------------
//
// Reference Methods.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// VMotionTrack::getPath();
//
// Returns the path that this track is referencing.
//
//-----------------------------------------------------------------------------
VTorque::PathObjectType *VMotionEvent::getPath( void )
{
// Fetch Track.
VMotionTrack *track;
if ( !getTrack( track ) )
{
// Invalid.
return NULL;
}
// Return Path.
return track->getPath();
}
//-----------------------------------------------------------------------------
//
// VMotionTrack::getObjectSpeed();
//
// Determine the Speed that an object must move at to travel over the segment
// length of the Path.
//
//-----------------------------------------------------------------------------
F32 VMotionEvent::getObjectSpeed( void )
{
// Fetch Parent Track.
VMotionTrack *track;
if ( !getTrack( track ) )
{
// Invalid Track.
return 0.f;
}
// Fetch Path & Reference Object.
VTorque::PathObjectType *path = track->getPath();
VTorque::SceneObjectType *object = getSceneObject();
if ( !path || !object )
{
// Invalid Object(s).
return 0.f;
}
// Fetch Node Index.
const S32 &srcNodeIndex = getNodeIndex( ( isControllerPlayingForward() ) ? 0 : -1 );
// Fetch the Next Event.
VEvent *nextEvent = getNextEvent();
// Valid Destination Node?
if ( !isControllerLooping() && !nextEvent )
{
// No Next Node.
return 0.f;
}
// Valid Next Node?
if ( nextEvent )
{
// Fetch Segment Length & Duration.
const F32 &length = VTorque::getPathNodeLength( path, srcNodeIndex );
const F32 &duration = mAbs( getTriggerTime() - nextEvent->getTriggerTime() );
// Speed = Distance / Duration.
return ( length / ( duration / 1000.f ) );
}
// Playing Forwards?
if ( isControllerPlayingForward() )
{
// Fetch the First Event.
VEvent *firstEvent = dynamic_cast<VEvent*>( track->getChild() );
// Fetch Segment Length & Duration.
const F32 &length = VTorque::getPathNodeLength( path, srcNodeIndex );
const F32 &duration = ( getControllerDuration() - getTriggerTime() ) + firstEvent->getTriggerTime();
// Speed = Distance / Duration.
return ( length / ( duration / 1000.f ) );
}
// Fetch the Last Event.
VEvent *lastEvent = dynamic_cast<VEvent*>( track->getLastChild() );
// Fetch Segment Length & Duration.
const F32 &length = VTorque::getPathNodeLength( path, srcNodeIndex );
const F32 &duration = ( getControllerDuration() - lastEvent->getTriggerTime() ) + getTriggerTime();
// Speed = Distance / Duration.
return ( length / ( duration / 1000.f ) );
}
//-----------------------------------------------------------------------------
//
// VMotionEvent::getNodeIndex( pDelta );
//
// Returns the index of the path node associated with this event object.
//
//-----------------------------------------------------------------------------
S32 VMotionEvent::getNodeIndex( const S32 &pDelta )
{
// Fetch Event Count.
const S32 eventCount = ( ( VTreeNode* )getParent() )->size();
// Return Index.
return ( getIndex() + pDelta ) % eventCount;
}

View file

@ -0,0 +1,61 @@
//-----------------------------------------------------------------------------
// 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_VMOTIONEVENT_H_
#define _VT_VMOTIONEVENT_H_
#ifndef _VT_VSCENEOBJECTEVENT_H_
#include "Verve/Extension/SceneObject/VSceneObjectEvent.h"
#endif
#ifndef _VT_TORQUE_MOTION_H_
#include "Verve/Torque/TMotion.h"
#endif
//-----------------------------------------------------------------------------
class VMotionEvent : public VSceneObjectEvent
{
typedef VSceneObjectEvent Parent;
public:
VMotionEvent( void );
// Event Methods.
virtual void onTrigger( const S32 &pTime, const S32 &pDelta );
// Reference Methods.
virtual VTorque::PathObjectType *getPath( void );
F32 getObjectSpeed( void );
S32 getNodeIndex( const S32 &pDelta = 0 );
// Console Declaration.
DECLARE_CONOBJECT( VMotionEvent );
};
//-----------------------------------------------------------------------------
#endif // _VT_VMOTIONEVENT_H_

View file

@ -0,0 +1,442 @@
//-----------------------------------------------------------------------------
// 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/Core/VGroup.h"
#include "Verve/Extension/Motion/VMotionTrack.h"
#include "Verve/Extension/Motion/VMotionEvent.h"
#include "console/consoleTypes.h"
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT( VMotionTrack );
//-----------------------------------------------------------------------------
VMotionTrack::VMotionTrack( void ) :
mDataReference( String::EmptyString ),
mOrientationMode( "FREE" ),
mOrientationData( String::EmptyString ),
mRelative( false )
{
setLabel( "MotionTrack" );
}
void VMotionTrack::initPersistFields( void )
{
Parent::initPersistFields();
addField( "Reference", TypeRealString, Offset( mDataReference, VMotionTrack ), "The name of the data field referencing the object to be attached to the path." );
addProtectedField( "OrientationMode", TypeRealString, Offset( mOrientationMode, VMotionTrack ), &setOrientationMode, &defaultProtectedGetFn, "The orientation mode of the object attached to the path." );
addProtectedField( "OrientationData", TypeRealString, Offset( mOrientationData, VMotionTrack ), &setOrientationData, &defaultProtectedGetFn, "The name of the data field holding the orientation data (used for Orientation Modes, ToObject & ToPoint)." );
addField( "Relative", TypeBool, Offset( mRelative, VMotionTrack ), "Attach the object with an offset based on its initial position." );
}
//-----------------------------------------------------------------------------
//
// Controller Methods.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// VMotionTrack::onControllerEvent( pEvent );
//
// When the controller's state changes, this method is called. If the
// controller is paused, then the path object will cease to move. If the
// controller resumes play, the object will continue on its path.
//
// For a full list of possible events, see the 'eControllerEventType'
// declaration in VController.h.
//
//-----------------------------------------------------------------------------
bool VMotionTrack::onControllerEvent( VController::eControllerEventType pEvent )
{
if ( !Parent::onControllerEvent( pEvent ) )
{
// Skip.
return false;
}
// Enabled?
if ( !isEnabled() )
{
// Continue Processing Events.
return true;
}
// Fetch Path & Reference Object.
VTorque::PathObjectType *path = getPath();
VTorque::SceneObjectType *object = getSceneObject();
if ( !path || !object || !VTorque::isPathObjectAttached( path, object ) )
{
// Invalid.
return true;
}
switch ( pEvent )
{
case VController::k_EventPlay :
{
// Continue Advancing.
VTorque::setPathObjectActive( path, object, true );
} break;
case VController::k_EventPause :
{
// Stop Advancing.
VTorque::setPathObjectActive( path, object, false );
} break;
case VController::k_EventStop :
{
// Detach the Object.
detachObject();
} break;
}
return true;
}
//-----------------------------------------------------------------------------
//
// VMotionTrack::onControllerReset( pTime, pForward );
//
// Reposition the path object on the path appropriately. The position is
// interpolated between two nodes, the last node and the next node. These
// correspond to the last and current events.
//
//-----------------------------------------------------------------------------
void VMotionTrack::onControllerReset( const S32 &pTime, const bool &pForward )
{
// Parent Reset.
Parent::onControllerReset( pTime, pForward );
// Valid Track?
// Note: We must have at least 2 Events/Nodes to path.
if ( size() < 2 )
{
// Invalid.
return;
}
// Get Object References.
VController *controller = getController();
VTorque::PathObjectType *path = getPath();
VTorque::SceneObjectType *object = getSceneObject();
if ( !controller || !path || !object )
{
// Invalid Object(s).
return;
}
// Attached?
if ( !VTorque::isPathObjectAttached( path, object ) )
{
// No, Attach Now.
attachObject();
}
// Reset Object.
resetObject( pTime );
}
//-----------------------------------------------------------------------------
//
// Reference Methods.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// VMotionTrack::getPath();
//
// Returns the path that this track is referencing.
//
//-----------------------------------------------------------------------------
VTorque::PathObjectType *VMotionTrack::getPath( void )
{
// Fetch the Controller.
VController *controller = getController();
if ( !controller )
{
// Invalid Controller.
return NULL;
}
// Evalulate the Data Field.
String fieldValue;
if ( controller->getDataValue( mDataReference, fieldValue ) )
{
// Return Object.
return dynamic_cast<VTorque::PathObjectType*>( Sim::findObject( fieldValue ) );
}
// No Data!
return NULL;
}
//-----------------------------------------------------------------------------
//
// VMotionTrack::attachObject();
//
// Attach the underlying Scene Object to the target Path at the first Node.
// Default settings are applied and must be updated after the object is
// attached.
//
//-----------------------------------------------------------------------------
void VMotionTrack::attachObject( void )
{
// Get Object References.
VTorque::PathObjectType *path = getPath();
VTorque::SceneObjectType *object = getSceneObject();
if ( !path || !object )
{
// Invalid Object(s).
return;
}
// Object Attached?
if ( VTorque::isPathObjectAttached( path, object ) )
{
// Already Attached.
return;
}
// Fetch Forwards.
const bool &forward = isControllerPlayingForward();
// Select the Node.
const S32 node = ( forward ) ? 0 : ( size() - 1 );
// Fetch the value from the controller data table.
String orientationDataValue = String::EmptyString;
if ( mOrientationData != String::EmptyString
&& !getController()->getDataValue( mOrientationData, orientationDataValue ) )
{
// Sanity!
Con::warnf( "Unable to located the value for the given orientation data key, '%s'", mOrientationData );
// Clear.
orientationDataValue = String::EmptyString;
}
// Attach Object.
VTorque::attachPathObject( path, object, forward, mRelative, node, -1, mOrientationMode, orientationDataValue );
}
//-----------------------------------------------------------------------------
//
// VMotionTrack::detachObject( void );
//
//
//
//-----------------------------------------------------------------------------
void VMotionTrack::detachObject( void )
{
// Get Object References.
VTorque::PathObjectType *path = getPath();
VTorque::SceneObjectType *object = getSceneObject();
if ( !path || !object )
{
// Invalid Object(s).
return;
}
// Object Attached?
if ( !VTorque::isPathObjectAttached( path, object ) )
{
// Not Attached.
return;
}
// Detach.
VTorque::detachPathObject( path, object );
}
//-----------------------------------------------------------------------------
//
// VMotionTrack::resetObject( pTime );
//
//
//
//-----------------------------------------------------------------------------
void VMotionTrack::resetObject( const S32 &pTime )
{
// Get Object References.
VTorque::PathObjectType *path = getPath();
VTorque::SceneObjectType *object = getSceneObject();
if ( !path || !object )
{
// Invalid Object(s).
return;
}
// Fetch Controller Info.
const bool &isPlaying = isControllerPlaying();
const bool &isPlayingForward = isControllerPlayingForward();
const bool &isLooping = isControllerLooping();
// Init Variables.
bool objectActive = false;
F32 objectInterp = 0.f;
F32 objectSpeed = 0.f;
S32 srcNodeIndex = 0;
S32 dstNodeIndex = 0;
VMotionEvent *event;
if ( !getNextEvent( event ) || event->getTriggerTime() == pTime )
{
// Note: This case deals with a target time that is greater than the
// trigger time of the Last Event on this track. It will clamp
// the position of the object to the corresponding node of the
// Last Event.
// Note: If pTime is exactly equal to the Next Event's trigger time,
// then it will set the Source Node to the Last Node and
// set its Interp to 0.f - which is incorrect!
if ( !event || event->getTriggerTime() != pTime )
{
// Fetch the Last Event.
getPreviousEvent( event );
}
// Set the Info.
objectInterp = 0.f;
objectSpeed = event->getObjectSpeed();
srcNodeIndex = event->getNodeIndex();
dstNodeIndex = srcNodeIndex;
}
else if ( !event->getPreviousEvent() )
{
// Note: This case deals with a target time that is less than the
// trigger time of the First Event on this track. It will clamp
// the position of the object to the corresponding node of the
// First Event.
// Set the Info.
objectInterp = 0.f;
objectSpeed = event->getObjectSpeed();
srcNodeIndex = event->getNodeIndex();
dstNodeIndex = srcNodeIndex;
}
else
{
// Note: This case deals with a target time that is between two Events
// on this track. It will position the object on the path,
// between the two nodes corresponding to the Events.
// Fetch the Last Event.
VMotionEvent *lastEvent;
getPreviousEvent( lastEvent );
// Set the Info.
objectActive = isPlaying;
objectInterp = calculateInterp( pTime );
objectSpeed = lastEvent->getObjectSpeed();
srcNodeIndex = event->getNodeIndex( ( isPlayingForward ) ? -1 : 1 );
dstNodeIndex = event->getNodeIndex();
}
// Set Active.
VTorque::setPathObjectActive( path, object, objectActive );
// Set Forward.
VTorque::setPathObjectForward( path, object, isPlayingForward );
// Set Speed.
VTorque::setPathObjectSpeed( path, object, objectSpeed );
// Set Current Node.
VTorque::setPathObjectNode( path, object, srcNodeIndex );
// Set End Node.
VTorque::setPathObjectEndNode( path, object, ( ( isLooping ) ? -1 : ( size() - 1 ) ) );
// Set Interp.
VTorque::setPathObjectInterp( path, object, objectInterp );
}
//-----------------------------------------------------------------------------
//
// Static Field Methods.
//
//-----------------------------------------------------------------------------
bool VMotionTrack::setOrientationMode( void *pObject, const char *pArray, const char *pData )
{
// Fetch Track.
VMotionTrack *track = static_cast<VMotionTrack*>( pObject );
// Store Data.
track->mOrientationMode = pData;
VTorque::PathObjectType *path = track->getPath();
VTorque::SceneObjectType *object = track->getSceneObject();
if ( VTorque::isPathObjectAttached( path, object ) )
{
// Set Orientation Mode.
VTorque::setPathObjectOrientation( path, object, track->mOrientationMode, track->mOrientationData );
}
return false;
}
bool VMotionTrack::setOrientationData( void *pObject, const char *pArray, const char *pData )
{
// Fetch Track.
VMotionTrack *track = static_cast<VMotionTrack*>( pObject );
// Store Data.
track->mOrientationData = pData;
VTorque::PathObjectType *path = track->getPath();
VTorque::SceneObjectType *object = track->getSceneObject();
if ( VTorque::isPathObjectAttached( path, object ) )
{
// Set Orientation Mode.
VTorque::setPathObjectOrientation( path, object, track->mOrientationMode, track->mOrientationData );
}
return false;
}
#ifdef VT_EDITOR
//-----------------------------------------------------------------------------
//
// Debug Methods.
//
//-----------------------------------------------------------------------------
ConsoleMethod( VMotionTrack, getPath, S32, 2, 2, "( void ) - Get the path object this track references.\n"
"@return Returns the SimObjectID for the object." )
{
// Fetch Path.
SimObject *pathReference = object->getPath();
// Return.
return ( pathReference ) ? pathReference->getId() : 0;
}
#endif

View file

@ -0,0 +1,85 @@
//-----------------------------------------------------------------------------
// 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_VMOTIONTRACK_H_
#define _VT_VMOTIONTRACK_H_
#ifndef _VT_VSCENEOBJECTTRACK_H_
#include "Verve/Extension/SceneObject/VSceneObjectTrack.h"
#endif
#ifndef _VT_TORQUE_MOTION_H_
#include "Verve/Torque/TMotion.h"
#endif
//-----------------------------------------------------------------------------
class VMotionTrack : public VSceneObjectTrack
{
typedef VSceneObjectTrack Parent;
public:
// Reference Members.
String mDataReference;
// Path Members.
String mOrientationMode;
String mOrientationData;
bool mRelative;
public:
VMotionTrack( void );
static void initPersistFields( void );
// Controller Methods.
virtual bool onControllerEvent( VController::eControllerEventType pEvent );
virtual void onControllerReset( const S32 &pTime, const bool &pForward );
// Reference Methods.
VTorque::PathObjectType *getPath( void );
void attachObject( void );
void detachObject( void );
void resetObject( const S32 &pTime );
// Console Declaration.
DECLARE_CONOBJECT( VMotionTrack );
protected:
// Static Field Methods.
static bool setOrientationMode( void *pObject, const char *pArray, const char *pData );
static bool setOrientationData( void *pObject, const char *pArray, const char *pData );
};
//-----------------------------------------------------------------------------
#endif // _VT_VMOTIONTRACK_H_